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

时间:2015-02-24 09:34:56

标签: c# asynchronous .net-4.0 async-await

是否可以在不使用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();
    }

2 个答案:

答案 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()