【问题标题】:Async with await do not work. Why?与等待异步不起作用。为什么?
【发布时间】:2013-05-14 09:59:22
【问题描述】:

当我尝试运行下面的代码时,执行同步操作。 为什么?

我收到以下警告...

警告 1 此异步方法缺少“等待”运算符,将同步运行。考虑使用 'await' 运算符来等待非阻塞 API 调用,或使用 'await Task.Run(...)' 在后台线程上执行 CPU 密集型工作。

private async void btProcessa_Click(object sender, EventArgs e)
{
    await ProcessaA();
    await ProcessaB();
}

public async Task ProcessaA()
{
    for (int i = 0; i <= 100; i++)
    {
        pbProcessoA.Value = i;
        Thread.Sleep(500);
    }
}

public async Task ProcessaB()
{
    for (int i = 0; i <= 100; i++)
    {
        pbProcessoB.Value = i;
        Thread.Sleep(500);
    }
}

【问题讨论】:

  • 详细信息的哪一部分不明白?我们需要知道才能具体回答。
  • 这个问题看起来像是Using async without await的骗子

标签: c# task-parallel-library .net-4.5 async-await


【解决方案1】:

async 并不意味着“在后台线程上运行此代码”。如果您想了解更多关于async 的信息,我有一个introductory blog postMSDN docs 很棒,还有一个full guide to the Task-based Asynchronous Pattern

如果您想对 I/O 绑定(或基于事件)操作进行一些模拟,您应该使用 Task.Delay 而不是 Thread.Sleep

public async Task ProcessaA()
{
  for (int i = 0; i <= 100; i++)
  {
    pbProcessoA.Value = i;
    await Task.Delay(500);
  }
}

如果您想模拟 CPU 密集型操作,那么您应该通过 Task.Run 将它们推送到后台任务:

public async Task ProcessaA()
{
  for (int i = 0; i <= 100; i++)
  {
    pbProcessoA.Value = i;
    await Task.Run(() => { Thread.Sleep(500); });
  }
}

【讨论】:

【解决方案2】:

我将这个示例写到了一个真实的生产系统中。将实体保存在数据库中可能需要一些时间。看看这个优雅的模拟

class TestAsyncAwait
{
    public void GetEntities()
    {
        for (int i = 0; i < 4; i++)
        {
            var a = getEntities(i);
            saveEntitiesAsync(a);
        }
        Console.WriteLine("\nPress any key to close\n");
        Console.ReadKey();
    }

    private List<string> getEntities(int i)
    {
        Console.Write("getting Entities for id={0}...", i);
        Thread.Sleep(2000);
        var r = new List<string> { i.ToString(), " Hello!" };
        Console.WriteLine("done, has the Entities for id={0}\n", i);
        return r;
    }

    async void saveEntitiesAsync(List<string> a)
    {
        var sb = new StringBuilder();
        await Task.Run(() =>
        {
            Thread.Sleep(4000); // simulates long task
            foreach (string s in a) sb.Append(s);
        });
        // shows the thread in action
        Trace.WriteLine("saved: " + sb.ToString());
    }
}

【讨论】:

    猜你喜欢
    • 2021-12-30
    • 1970-01-01
    • 2023-04-07
    • 2018-06-06
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多