在 .net 4.0 中用 task.continuewith 模拟 async/await

Simulate async/await with task.continuewith in .net 4.0

是否可以在 .NET 4.0 中模拟 async/await 的行为而不使用 Microsoft.Bcl.Async 包?

我试过了运行

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

但这会阻止我的 UI 而 myTask 是 运行。在搜索此问题时,我发现 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();
    }

可以在没有编译器和框架帮助的情况下模仿 async-await,尽管很难做到正确。您需要注意捕获上下文、异常处理、返回结果等。

您提到的情况不应在整个异步操作期间阻塞 UI。然而,在异步操作(如 DNS 解析)之前可能会进行一些同步工作。如果是这种情况,请使用 Task.Run 并将该工作卸载到 ThreadPool 线程以提高响应能力。

Task myTask = Task.Factory.Startnew(MyMethod)
myTask.ContinueWith((x)=>
{
    //do stuff when myTask is completed
},new CancellationToken(),TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.FromCurrentSynchronizationContext());

这意味着继续不会阻塞您的 UI 线程。这里最主要的是TaskScheduler.FromCurrentSynchronisationContext()