【发布时间】:2015-02-24 18:17:51
【问题描述】:
是否可以在不使用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?
编辑:根据用户 1 的请求阻止我的 UI 的示例代码
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();
}
【问题讨论】:
-
如果您发布一个特定的最小示例,我们可以准确地告诉您它是否阻塞。否则只是猜测。
-
你能告诉我们这个方法执行的完整上下文吗?您是否将任何
TaskScheduler传递给它?我们需要更多代码。 -
就像你在我的编辑中看到的那样,我使用
TaskScheduler.FromCurrentSynchronizationContext()。我认为这是默认设置 - 这是否意味着我的执行任务也在当前同步上下文中运行?! -
使用 TaskScheduler.Default 不会阻止我的用户界面...我想这毕竟是一个愚蠢的问题 ^^ 谢谢你的帮助!
-
@HW 从你的任务中取出
, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());。您正在通过将代码放在那里来在当前 UI 线程上运行您的任务。因此您阻止了 UI
标签: c# asynchronous .net-4.0 async-await