Reputation: 2596
Is it possible to simulate the behaviour of async/await in .NET 4.0 without using the Microsoft.Bcl.Async
Package?
I tried running
Task myTask = Task.Factory.Startnew(MyMethod,...)
myTask.ContinueWith((x)=>{
//do stuff when myTask is completed
},...);
//code that i hoped would run without waiting for myTask
but this blocks my UI while myTask is running. When searching for this issue, i found this question which seems to ask the exact same thing and even presents a solution with a full code sample. However when i tried calling GetResponseWithRetryAsync
(or running it with task.Start()
, or wrapping it in Task.Factory.StartNew()
) it still blocks my UI thread. Why are all these ways of running a task blocking my UI?
edit: sample code which blocks my UI as requested by user1
Task myTask = Task.Factory.StartNew(MyMethod, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
myTask.ContinueWith((x) =>
{
this.Title="Done!";
}, new CancellationToken(), TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext());
where MyMethod
is
public void MyMethod(){
WebRequest request = WebRequest.Create("http://google.com/");
request.Credentials = CredentialCache.DefaultCredentials;
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
reader.Close();
response.Close();
}
Upvotes: 1
Views: 2449
Reputation: 18827
Task myTask = Task.Factory.Startnew(MyMethod)
myTask.ContinueWith((x)=>
{
//do stuff when myTask is completed
},new CancellationToken(),TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.FromCurrentSynchronizationContext());
This means that the continue with wont block your UI thread. The main thing here is TaskScheduler.FromCurrentSynchronisationContext()
Upvotes: 1
Reputation: 116636
It is possible to imitate async-await
without the compiler and framework's help, although extremely difficult to get right. You need to take care of capturing context, exception handling, returning a result and so forth.
The cases you mentioned aren't supposed to block the UI throughout the asynchronous operation. However there may be some synchronous work being done before the asynchronous operation like DNS resolution. If that's the case, use Task.Run
and offload that work to a ThreadPool
thread to improve responsiveness.
Upvotes: 3