仅使用异步任务和任务有什么区别?

时间:2016-06-18 05:43:59

标签: c# asynchronous parallel-processing task-parallel-library task

例如,此代码之间的区别

public Task<IList<NewsSentimentIndexes>> GetNewsSentimentIndexes(DateTime @from, DateTime to = new DateTime(), string grouping = "1h")
    {
        var result = _conf.BasePath
            .AppendPathSegment("news-sentiment-indexes")
            .SetQueryParams(new
            {
                from = from.ToString("s"),
                to = to.ToString("s"),
                grouping
            });

        return result
           .GetStringAsync()
           .ContinueWith(Desereialize<IList<NewsSentimentIndexes>>);
    }

那个

 public async Task<IList<NewsSentimentIndexes>> GetNewsSentimentIndexes(DateTime @from, DateTime to = new DateTime(), string grouping = "1h")
    {
        var result = _conf.BasePath
            .AppendPathSegment("news-sentiment-indexes")
            .SetQueryParams(new
            {
                from = from.ToString("s"),
                to = to.ToString("s"),
                grouping
            });

        var newsStr =  await result.GetStringAsync();
        return JsonConvert.DeserializeObject<NewsSentimentIndexes>(newsStr);
    }

哪一个工作正确或更快? 只需要调用此方法需要等待或只是一个任务?

3 个答案:

答案 0 :(得分:6)

async更好。您应该始终使用await代替ContinueWith。我在博客上详细介绍why ContinueWith is bad

这两种实现之间的语义差异是由于两个不同之处:是否使用了async,以及是否使用了ContinueWith

删除async会更改异常语义。使用async时,会捕获任何异常(由编译器生成的状态机)并放在返回的任务上。如果没有async,则会直接(同步)引发异常。因此,如果BasePathAppendPathSegmentSetQueryParamsGetStringAsync抛出(或返回null或类似的东西),则该异常将同步引发而不是异步,这可能会使来电者感到困惑。

使用ContinueWith更改执行语义。在这种情况下,Deserialize将在TaskScheduler.Current上进行安排。这种对当前TaskScheduler的依赖是ContinueWith中最棘手的部分之一。

答案 1 :(得分:5)

两种方法都返回相同的类型:Task。但async方法允许在其身体中使用await关键字。它通知编译器生成await及其全部的状态机。关于async / await性能,您可以阅读this post

答案 2 :(得分:-3)

Async Task返回对象,而Task则不返回。

所以你可以使用异步任务执行此操作:

var yourTask = AsyncTask()

虽然您可以使用正常任务执行此操作:

NormalTask().someFunction()