c# – Task.Run与直接异步调用,用于启动长时间运行的异步方法

前端之家收集整理的这篇文章主要介绍了c# – Task.Run与直接异步调用,用于启动长时间运行的异步方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有好几次,我发现自己编写了长时间运行的异步方法,比如轮询循环.这些方法可能如下所示:
private async Task PollLoop()
{
    while (this.KeepPolling)
    {
        var response = await someHttpClient.GetAsync(...).ConfigureAwait(false);
        var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

        // do something with content

        await Task.Delay(timeBetweenPolls).ConfigureAwait(false);
    }
}

为此目的使用异步的目的是我们不需要专用的轮询线程,但逻辑(对我而言)比直接使用像计时器这样的东西更容易理解(也就是说,不需要担心重入).

我的问题是,从同步上下文启动这样一个循环的首选方法是什么?我能想到至少两种方法

var pollingTask = Task.Run(async () => await this.PollLoop());

// or

var pollingTask = this.PollLoop();

在任何一种情况下,我都可以使用ContinueWith()来响应异常.我对这两种方法之间差异的主要理解是,第一个将首先在线程池线程上开始循环,而第二个将在当前线程上运行,直到第一个等待.这是真的?还有其他需要考虑的事项或更好的方法吗?

解决方法

My main understanding of the difference between these two methods is
that the first will initially start looping on a thread-pool thread,
whereas the second will run on the current thread until the first
await. Is this true?

是.异步方法在第一次等待尚未完成的等待时将其任务返回给其调用者.

按照惯例,大多数异步方法返回非常快.你也可以,因为等待一些HttpClient.GetAsync将很快到达.

将这个异步方法的开头移到线程池上是没有意义的.它增加了开销,几乎没有延迟.它当然无助于吞吐量或扩展行为.

在这里使用异步lambda(Task.Run(async()=> await this.PollLoop()))尤其无用.它只是将PollLoop返回的任务包含在另一层任务中.最好说Task.Run(()=> this.PollLoop()).

原文链接:https://www.f2er.com/csharp/100058.html

猜你在找的C#相关文章