你必须把Task.Run的方法,使之异步? [英] Do you have to put Task.Run in a method to make it async?

查看:185
本文介绍了你必须把Task.Run的方法,使之异步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解异步等待最简单的形式。我想创建一个非常简单的方法,两数相加的这个例子的目的,理所当然的,这是没有的处理时间可言,它只是一个在这里制定一个例子的问题。

实施例1:

 专用异步任务DoWork1Async()
{
    INT结果= 1 + 2;
}

例2:

 专用异步任务DoWork2Async()
{
    Task.Run(()=>
    {
        INT结果= 1 + 2;
    });
}

如果我在等待着DoWork1Async()将在code运行同步或异步?

我是否需要换同步code。与Task.Run使方法awaitable和异步以免阻塞UI线程?

我试图找出如果我的方法是一个任务或返回的任务,我需要换行code。与Task.Run使其异步的。

愚蠢的问题我敢肯定,但我看到那里的人们正在等待code有什么异步之内,而不是包裹在Task.Run或StartNew在网络上的例子。


解决方案

首先,让我们澄清一些术语:异步(异步),意味着它可能会放弃控制回调用线程开始之前。在异步方法,这些收益点的await 前pressions。

这是比异步一词很不同,因为多年使用的MSDN文档意味着执行在后台线程。

(MIS)

要进一步的混淆问题,异步比awaitable非常不同。有返回awaitable类型不在异步。<一些异步方法的返回类型不是awaitable,许多方法/ p>

够关于他们的的;这里就是他们的的:


  • 异步关键字允许异步方法(即,它允许的await 前pressions)。 异步方法可以返回工作任务&LT; T&GT; ,或者(如果必须)无效

  • 遵循一定的模式可以是awaitable任何类型。最常见的awaitable类型是工作任务&LT; T&GT;

所以,如果我们改写你的问题:我怎么可以运行在后台线程的的方式,它是awaitable操作的,答案是使用任务。运行

 私人任务&LT; INT&GT; DoWorkAsync()//没有异步因为该方法不需要AWAIT
{
  返回Task.Run(()=&GT;
  {
    返回1 + 2;
  });
}

(但是这种模式是一个贫穷的办法;见下文)。

但是,如果你的问题是我怎么创建一个异步方法,可以产生回它的调用者而不是阻塞的,答案是申报方法异步,并使用等待以其屈服点:

 专用异步任务&LT; INT&GT; GetWebPageHtmlSizeAsync()
{
  VAR的客户=新的HttpClient();
  VAR HTML =等待client.GetAsync(http://www.example.com/);
  返回html.Length;
}

所以,物联网的基本格局是有异步 code在其靠awaitables的await 前pressions。这些awaitables可以是其他异步方法或只是普通的方法返回awaitables。常规方法返回工作 / 任务&LT; T&GT; 可以的使用 Task.Run 来在后台线程中执行code或(更常见),他们可以使用 TaskCompletionSource&LT; T&GT; 或之一其快捷键( TaskFactory.FromAsync Task.FromResult 等)。 我不建议在包装的整个法 Task.Run ;同步的方法应该有同步的签名,应该留给消费者是否应该被包裹在一个 Task.Run

 私人诠释的DoWork()
{
  返回1 + 2;
}私人无效MoreSynchronousProcessing()
{
  //执行它直接(同步),因为我们也有同步的方法。
  VAR的结果=的DoWork();
  ...
}私人异步任务DoVariousThingsFromTheUIThreadAsync()
{
  //我有一大堆的异步工作要做,而我在UI线程上执行。
  变种结果=等待Task.Run(()=&GT; DoWork的());
  ...
}

我有一个<一个href=\"http://blog.stephencleary.com/2012/02/async-and-await.html\"><$c$c>async/<$c$c>await引导页在我的博客;在最后有一些很好的后续资源。 MSDN文档为异步都异常不错。

I'm trying to understand async await in the simplest form. I want to create a very simple method that adds two numbers for the sake of this example, granted, it's no processing time at all, it's just a matter of formulating an example here.

Example 1:

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

Example 2:

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

If I await DoWork1Async() will the code run synchronously or asynchronously?

Do I need to wrap the sync code with Task.Run to make the method awaitable AND asynchronous so as not to block the UI thread?

I'm trying to figure out if my method is a Task or returns Task do I need to wrap the code with Task.Run to make it asynchronous.

Stupid question I'm sure but I see examples on the net where people are awaiting code that has nothing async within and not wrapped in a Task.Run or StartNew.

解决方案

First, let's clear up some terminology: "asynchronous" (async) means that it may yield control back to the calling thread before it starts. In an async method, those "yield" points are await expressions.

This is very different than the term "asynchronous", as (mis)used by the MSDN documentation for years to mean "executes on a background thread".

To futher confuse the issue, async is very different than "awaitable"; there are some async methods whose return types are not awaitable, and many methods returning awaitable types that are not async.

Enough about what they aren't; here's what they are:

  • The async keyword allows an asynchronous method (that is, it allows await expressions). async methods may return Task, Task<T>, or (if you must) void.
  • Any type that follows a certain pattern can be awaitable. The most common awaitable types are Task and Task<T>.

So, if we reformulate your question to "how can I run an operation on a background thread in a way that it's awaitable", the answer is to use Task.Run:

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

(But this pattern is a poor approach; see below).

But if your question is "how do I create an async method that can yield back to its caller instead of blocking", the answer is to declare the method async and use await for its "yielding" points:

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

So, the basic pattern of things is to have async code depend on "awaitables" in its await expressions. These "awaitables" can be other async methods or just regular methods returning awaitables. Regular methods returning Task/Task<T> can use Task.Run to execute code on a background thread, or (more commonly) they can use TaskCompletionSource<T> or one of its shortcuts (TaskFactory.FromAsync, Task.FromResult, etc). I don't recommend wrapping an entire method in Task.Run; synchronous methods should have synchronous signatures, and it should be left up to the consumer whether it should be wrapped in 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());
  ...
}

I have an async/await intro on my blog; at the end are some good followup resources. The MSDN docs for async are unusually good, too.

这篇关于你必须把Task.Run的方法,使之异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆