【问题标题】:Understanding Task based asynchronous pattern C#了解基于任务的异步模式 C#
【发布时间】:2017-04-22 06:14:23
【问题描述】:

我开始学习 C# TAP 编码。我不明白为什么代码是同步运行的

    async private void timer1_Tick(object sender, EventArgs e)
    {
        SyncCount++;
        result1.Text = SyncCount.ToString();

        AsyncCount = await CountForALongTimeAsync(AsyncCount);
        result2.Text = AsyncCount.ToString();
    }

    async Task<int> CountForALongTimeAsync(int counter)
    {
        Thread.Sleep(3000);
        counter++;
        return counter;
    }

【问题讨论】:

  • Thread.Sleep 更改为await Task.Delay
  • 你怎么理解是同步的还是异步的?我看到一个异步函数返回其(按值传递)参数增加了一个...
  • 您应该已经收到警告说您的CountForALongTimeAsync 方法没有await 表达式,因此将同步运行。很可能您应该阅读有关异步工作原理的教程……这不仅仅是一个神奇的“添加异步修饰符,它就变成了异步”功能。绝对值得合理彻底地理解它。
  • @GregaMohorko:不,它不是异步的,因为CountForALongTimeAsync 实际上是同步的。此代码阻塞 UI 线程。

标签: c# async-await


【解决方案1】:
async Task<int> CountForALongTimeAsync(int counter)
{

接下来会执行,直到第一个 awaited 异步调用实际上做了一些等待(给定的调用可能会立即返回所需的所有内容,例如,可能会访问互联网或可能返回的服务缓存中的数据,在这种情况下它不会等待)。

根本没有awaited 调用,因此返回的Task 已完成返回。

由于调用await CountForALongTimeAsyncawait,返回的任务已经完成,所以同步运行。

该方法会更好:

async Task<int> CountForALongTimeAsync(int counter)
{
    await Task.Delay(3000);
    counter++;
    return counter;
}

顺便说一句,以前 await 做一些非常(但不完全)相似的事情的方式是:

Task<int> CountForALongTimeAsync(int counter)
{
    return Task.Delay(3000).ContinueWith(t =>
    {
        ++counter;
        return counter;
    });
}

考虑到这些是在一项任务之后“继续”的不同想法可能会或可能不会提供一些见解。

相比之下,您问题中的代码所做的最接近的 pre-await 方式是:

Task<int> CountForALongTimeAsync(int counter)
{
    Thread.Sleep(3000);
    counter++;
    return Task.FromResult(counter); //FromResult returns an already completed task.
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 2014-06-19
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 2023-03-11
    相关资源
    最近更新 更多