栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Do you have to put Task.Run in a method to make it async?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Do you have to put Task.Run in a method to make it async?

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
pre 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 pre 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.



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/433073.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号