In a WebApi project I do a Post to convert some file to another:
var post = client.PostAsync(requestUri, content);
post.Wait();
var result = post.Result;
The result will contain the converted file so is important for me that current Thread to wait for the response before going further and use the result.
Well, it seems that it goes further and of course, the result is not ready yet... Do I do anything wrong here?
If you want to do synchronously, needless to call Wait(), just return Result directly, the Result property blocks the calling thread until the task finishes.
var response = client.PostAsync(requestUri, content).Result;
response.EnsureSuccessStatusCode();
In here, the content of result is still not ready yet, you need to continue to get the content:
var responseBody = response.Content.ReadAsStreamAsync().Result;
I've seen intermittent threading issues occur with the approach Cuong is recommending. Instead I suggest you use this approach:
var response = client
.PostAsync(requestUri, content)
.ContinueWith( responseTask => {
var result = responseTask.Result;
// .... continue with your logic ...
});
response.Wait();
The ContinueWith method is designed to guarantee your code will run once the original task completes or aborts.
Related
How does Dart run asynchronous code without blocking?
For example:
void test(User user) async {
print('test');
String fullName = user.firstName + ' ' + user.lastName;
final result = await sendRequest(fullName);
print('${result}');
}
I understand that when Dart runs async function, it executes code before await and then wraps the remaining code into Future and puts it into Event Loop. But, how does that Future what we're awaiting for (await sendRequest(fullName)) not blocking running the other, synchronous code? We should wait for request for complete but it also requires some code to check that we've received or not received response. How does it not block other operations, like button clicks?
The function returns at the first await. It returns a future which will later be completed (which is then ignored because of the void return type). Everything else in the function happens in reaction to callbacks from other futures (or streams, if you use await for).
The async function here is basically rewritten into something like:
void test(User user) {
print('test');
String fullName = user.firstName + ' ' + user.lastName;
return sendRequest(fullName).then((final result) { // <-- Returns here, synchronously.
print('${result}'); // <-- Gets called by the future of `sendRequst(fullName)`.
});
}
This transformation is similar to a continuation-passing style transformation in the it takes the continuation (the control flow in the body of the function after the await) and makes it into a function.
(In reality, the transformation is more complicated because it needs to account for loops, try/catch/finally, and even break statements. Because of that, even a simple example like this one will likely be converted into something more complicated than absolutely necessary).
Should I use taskThatReturns.Wait() in code below or I can omit it since according to my understanding taskThatReturns.Result will do wait anyway.
Task<string> taskThatReturns = new Task<string>(MethodThatReturns);
taskThatReturns.Start();
taskThatReturns.Wait();
Console.WriteLine(taskThatReturns.Result);
The call of Wait() before accessing Result is unnecessary.
Examination of the reference code of Task and Task<TResult> shows that both the void Wait() method and the getter of the Result property eventually make their way into the method that does the actual waiting:
internal bool InternalWait(int millisecondsTimeout, CancellationToken cancellationToken)
Both code paths send identical parameter values to InternalWait - infinite wait and default cancellation token.
If you call Wait before accessing Result, the code path inside the getter leading to InternalWait would be skipped, because the task is known to be completed. However, the net result would remain the same in both cases.
Note: This answer intentionally ignores opportunities to optimize your code fragment.
async void DoTask() {
string task = await returnString();
Console.WriteLine(task);
}
Task<string> returnString() {
// you code here
}
You can use async method to await Task execution
To answer the actual question. You either need to wait to get the results, or you need to do as Panagiotis Kanavos suggested, and await a task. You're overcomplicating threading, a common issue with all the bad examples out there.
If you still want to use Task better approach is:
var result = taskThatReturns.GetAwaiter().GetResult();
I work on a project with durandal/breeze. I have the following code in my activate function:
var activate = function (routeData) {
initLookups();
var idTran = parseInt(routeData.idTran);
var idItin = parseInt(routeData.idItin);
if (idItin == -1)
idItin = datacontext.createItineraryDetailTransport(idTran);
datacontext.getTransportById(idTran, transport);
datacontext.getItineraryById(idItin, itinerary);
}
As you can see in the above code, I have 3 calls to the datacontext:
datacontext.createItineraryDetailTransport >> eventually... if (idItin == -1)
datacontext.getTransportById
datacontext.getItineraryById
The problem right now is that each call is not waiting for the previous one to complete before executing.
My question: how to proceed to be sure one call is finished before executing the next one? Please note that the first call is inside a condition... I'm thinking of using 'promises' but don't know.
Thanks.
The tricky part to what you're trying to do is conditionally chain three calls together.
You can simply chain multiple calls together using the then() method. However in your case, you need an initial promise to chain when the first condition isn't met.
The $.when() method is the trick here, because you can either chain an promise returned by Breeze, or you can chain a "dummy" promise, which is what $.when() gives you. If the first parameter passed to $.when is not a promise, then it returns a promise that is immediately resolved.
If I understand your question correctly, you should be able to write your code something like this:
var activate = function (routeData) {
initLookups();
var idTran = parseInt(routeData.idTran);
var idItin = parseInt(routeData.idItin);
var idtDeferred = $.when();
if (idItin == -1)
idtDeferred = datacontext.createItineraryDetailTransport(idTran);
idtDeferred
.then(datacontext.getTransportById(idTran, transport))
.then(datacontext.getItineraryById(idItin, itinerary));
}
Your code example looks like datacontext.createItineraryDetailTransport is supposed to set the idItin var, but I'm assuming that it returns a promise like typical breeze queries.
Certain parts of your example are unclear to me.
Is initLookups asynchronous? If so, do you have to wait for it to complete before performing the other asynchronous steps?
How can createItineraryDetailTransport be asynchronous when it returns the integer, idItin?
What the heck does createItineraryDetailTransport actually do? My guess is that idItin == -1 when you don't have an ItineraryDetailTransport entity yet and therefore don't have the key you need to call getItineraryById. If so, you have to restructure the signature of createItineraryDetailTransport.
Why does getItineraryById have to wait for getTransportById when they seemingly have nothing in common?
What are transport and itinerary? I'm guessing they are accidentally omitted variables that will be set with the results of the async calls within those datacontext methods.
Where is your error handling? What should happen if one of the async calls fails?
These issues must be sorted out before someone can give you a really good answer.
Joseph Gabriel seems to me to be mostly on the right track although I might have written it a little differently
...
var transport, itinerary;
var promise = (idItin == -1) ?
datacontext.createItineraryDetailTransport(aCallBackThatSets_idItin) :
Q.resolve(); // creates a resolved promise
promise = promise
.then(datacontext.getTransportById(idTran, transport)
.then(datacontext.getItineraryById(idItin, itinerary))
.fail(yourErrorHandler);
return promise; // don't forget to return the promise!
The most important step missing from Joseph Gabriel's suggestion ... and the reason you couldn't make his suggestion work ... is that it neglected to return the promise.
You must return a promise if you want Durandal to wait before activating the view.
With the release of the new dart:io libraries, in order to read the data from an HttpRequest we now need to:
Listen to the body to handle data and notified of it's completion.
In order to accomplish this, I've been using something similar to the following to get all of the data from the request (taken from the dart:io tests):
List<int> body = new List<int>();
request.listen(body.addAll, onDone: () {
var str = new String.fromCharCodes(body);
// Now do something with the string of data
});
Is there some way of using transform and/or StringDecoders to already provide a constructed result. The only way I can think of, I would still need to create a StringBuffer and use writeAll to ensure all data is passed in the event it doesn't all arrive at once, and still call the onDone before using the string in the buffer.
So I guess ultimately the question is: is there some way I can use a HttpRequest (or in all actuality any Stream) without needing to buffer/build the results and can just pass a callback or handler which receives the entire contents?
I haven't tried this, but I think you should be able to use StringDecoder, toList() and join() to get the whole body:
request.transform(new StringDecoder()).toList().then((data) {
var body = data.join('');
print(body);
}
My application sends out some emails, and the image paths referenced in the e-mails need to vary depending on how the user accessed the page that is sending the email. I've used variations of the code before many times with no problem, but this is the first time I'm trying to do it in an MVC app:
var relImagePath = controllerContext.HttpContext.Response.ApplyAppPathModifier("~/Emails/Images");
var absImagePath = new Uri(controllerContext.HttpContext.Request.Url, relImagePath).AbsoluteUri;
The second line is throwing an NullReferenceException because HttpContext.Request.Url is null. How can that be?
Edit: I should note that I'm running this code in a thread pool thread separate from the one that processed the request. If I move this code back onto the thread executing the controller action, the url is there. For now, I've resorted to executing the code on the same thread.
The HttpContext might not always be accessible in threads. You will need to pass the required information to the thread:
var relImagePath = controllerContext.HttpContext.Response.ApplyAppPathModifier("~/Emails/Images");
var absImagePath = new Uri(controllerContext.HttpContext.Request.Url, relImagePath).AbsoluteUri;
new Thread(state =>
{
var imagePath = (string)state;
// TODO ...
}).Start(absImagePath);
or if you are using the ThreadPool (only for short running tasks):
ThreadPool.QueueUserWorkItem(state =>
{
var imagePath = (string)state;
// TODO ...
}, absImagePath);
I would suppose that RequestContext grabs current HttpContext at the time you call controllerContext.HttpContext (since it asks RequestContext for the HttpContext), and I suppose that it may just ask HttpContext.Current, and that's why get null.
Try to grab controllerContext.HttpContext in the ASP.NET thread, save it and pass to your own thread, instead of controller context which asks for HttpContext at wrong time later.
That's my guess.
Also, http://csharpfeeds.com/post/5415/Dont_use_the_ThreadPool_in_ASP.NET.aspx
This override also seems to work:
protected new UrlHelper Url
{
get { return base.Url ?? (base.Url = new UrlHelper(ControllerContext.RequestContext)); }
set { base.Url = value; }
}