加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 07:56:56 所属栏目:百科 来源:网络整理
导读:有好几次,我发现自己编写了长时间运行的异步方法,比如轮询循环.这些方法可能如下所示: private async Task PollLoop(){ while (this.KeepPolling) { var response = await someHttpClient.GetAsync(...).ConfigureAwait(false); var content = await respon
有好几次,我发现自己编写了长时间运行的异步方法,比如轮询循环.这些方法可能如下所示:
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()).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读