小编典典

您是否必须将 Task.Run 放入使其异步的方法中?

all

我试图以最简单的形式理解异步等待。为了这个例子,我想创建一个非常简单的方法,将两个数字相加,当然,这根本不需要处理时间,只是在这里制定一个例子。

示例 1

private async Task DoWork1Async()
{
    int result = 1 + 2;
}

示例 2

private async Task DoWork2Async()
{
    Task.Run( () =>
    {
        int result = 1 + 2;
    });
}

如果我等待DoWork1Async(),代码是同步运行还是异步运行?

我是否需要包装同步代码Task.Run以使方法可等待和异步,以免阻塞 UI 线程?

我试图弄清楚我的方法是 aTask还是返回Task<T>我是否需要包装代码Task.Run以使其异步。

愚蠢的问题我敢肯定,但我在网上看到一些例子,人们正在等待其中没有任何 async 并且没有包裹在Task.Runor中的代码StartNew


阅读 120

收藏
2022-04-04

共1个答案

小编典典

首先,让我们澄清一些术语:“异步”( async)
意味着它可能会在调用线程开始之前将控制权交还给调用线程。在一种async方法中,那些“屈服”点是await表达式。

这与术语“异步”非常不同,因为 MSDN 文档多年来(误用)来表示“在后台线程上执行”。

进一步混淆问题,async与“等待”有很大不同;有些async方法的返回类型不是可等待的,而许多方法返回的可等待类型不是async.

关于他们 不是 什么已经足够了;它们 是这样的

  • async关键字允许异步方法(即,它允许await表达式)。async方法可能返回Task, Task<T>, 或(如果必须的话)void
  • 任何遵循某种模式的类型都可以等待。最常见的等待类型是TaskTask<T>

因此,如果我们将您的问题重新表述为“如何以等待的方式在 后台线程上Task.Run运行操作”,答案是使用:

private Task<int> DoWorkAsync() // No async because the method does not need await
{
  return Task.Run(() =>
  {
    return 1 + 2;
  });
}

(但这种模式是一种糟糕的方法;见下文)。

但是,如果您的问题是“我如何创建一个async可以返回给调用者而不是阻塞的方法”,答案是声明该方法asyncawait用于其“让步”点:

private async Task<int> GetWebPageHtmlSizeAsync()
{
  var client = new HttpClient();
  var html = await client.GetAsync("http://www.example.com/");
  return html.Length;
}

因此,事物的基本模式是让代码在其表达式async中依赖于“等待对象”
await这些“等待”可以是其他async方法,也可以只是返回等待的常规方法。Task返回/的常规方法Task<T>
用于Task.Run在后台线程上执行代码,或者(更常见)它们可以使用TaskCompletionSource<T>或其快捷方式之一(TaskFactory.FromAsync,Task.FromResult等)。我
建议将整个方法包装在Task.Run; 同步方法应该具有同步签名,并且应该由消费者决定是否应该将其包装在 a 中Task.Run

private int DoWork()
{
  return 1 + 2;
}

private void MoreSynchronousProcessing()
{
  // Execute it directly (synchronously), since we are also a synchronous method.
  var result = DoWork();
  ...
}

private async Task DoVariousThingsFromTheUIThreadAsync()
{
  // I have a bunch of async work to do, and I am executed on the UI thread.
  var result = await Task.Run(() => DoWork());
  ...
}

我的博客上有async/await介绍;最后是一些很好的后续资源。MSDN 文档async也非常好。

2022-04-04