是否可以在不使用Microsoft.Bcl.Async
包的情况下模拟.NET 4.0中async / await的行为?
我试过了
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
但是这会在myTask运行时阻止我的UI。在搜索此问题时,我发现this question似乎问了完全相同的事情,甚至提出了一个包含完整代码示例的解决方案。但是,当我尝试调用GetResponseWithRetryAsync
(或使用task.Start()
运行它,或将其包装在Task.Factory.StartNew()
中)时,它仍会阻止我的UI线程。为什么所有这些运行任务的方式都会阻止我的UI?
编辑:根据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());
其中MyMethod
是
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();
}
答案 0 :(得分:2)
可以在没有编译器和框架帮助的情况下模仿async-await
,尽管很难做到正确。您需要注意捕获上下文,异常处理,返回结果等等。
您提到的案例不应该在整个异步操作中阻止UI。但是,在DNS解析等异步操作之前可能会进行一些同步工作。如果是这种情况,请使用Task.Run
并将该工作卸载到ThreadPool
主题以提高响应能力。
答案 1 :(得分:0)
Task myTask = Task.Factory.Startnew(MyMethod)
myTask.ContinueWith((x)=>
{
//do stuff when myTask is completed
},new CancellationToken(),TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.FromCurrentSynchronizationContext());
这意味着继续不会阻止你的UI线程。这里的主要内容是TaskScheduler.FromCurrentSynchronisationContext()