Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Task.Run()中执行Aync/wait操作_C#_.net_Asynchronous - Fatal编程技术网

C# 在Task.Run()中执行Aync/wait操作

C# 在Task.Run()中执行Aync/wait操作,c#,.net,asynchronous,C#,.net,Asynchronous,Task.Run(()=>{})将操作委托放入队列并返回任务。 在Task.Run()中使用async/await有什么好处吗? 我理解Task.Run()是必需的,因为如果我们想直接使用wait,那么调用方法将需要异步,并将影响调用位置 下面是在Task.Run()中包含async await的示例代码。此处提供了完整样本: 或者也可以这样做 Task.Run(() => new WebClient().DownloadStringTaskAsync("").Result;); 由于T

Task.Run(()=>{})
将操作委托放入队列并返回任务。 在Task.Run()中使用async/await有什么好处吗? 我理解Task.Run()是必需的,因为如果我们想直接使用wait,那么调用方法将需要异步,并将影响调用位置

下面是在Task.Run()中包含async await的示例代码。此处提供了完整样本:

或者也可以这样做

Task.Run(() => new WebClient().DownloadStringTaskAsync("").Result;);
由于Task.Run()和Await都将对工作进行排队,并由线程池选择,因此Task.Run()中的async/Await会有点冗余吗

在Task.Run()中使用async/await有什么好处吗

对<代码>任务。运行在线程池线程上运行某些操作。如果这样的操作执行一些IO工作,并通过
wait
异步等待IO操作完成,那么当IO操作仍在运行时,系统可以将此线程池线程用于其他工作

例如:

Task.Run( async () =>
{
    DoSomeCPUIntensiveWork();

    // While asynchronously waiting for this to complete, 
    // the thread is given back to the thread-pool
    var io_result = await DoSomeIOOperation(); 

    DoSomeOtherCPUIntensiveWork(io_result);
});

在您链接的示例中,主线程将被阻塞,直到异步操作完成。调用
Wait()
(顺便说一句,这通常是个坏主意)会阻止它

让我们看看示例中的
DownloadStringAsync
返回:

为什么要将其包装在
任务中
?考虑一下你的选择。如果您不想将其包装在
任务中
,如何确保该方法返回
任务
,并且仍然有效?当然,您会将该方法标记为
async
!但是,如果您将方法标记为
async
,并对其调用
Wait
,则很可能会导致死锁,因为主线程正在等待工作完成,并且您阻塞了主线程,因此无法让您知道它已完成

将方法标记为
async
时,状态机将在调用线程上运行,但是在您的示例中,状态机在单独的线程上运行,这意味着在主线程上几乎没有工作要做。

从非异步方法调用async 当我们试图在非异步方法中调用异步方法时,我们会做一些类似的事情。特别是当异步方法是已知数量时。不过我们更多地使用TaskFactory。。。适合一种模式,使调试更容易,确保每个人都采用相同的方法(并且--如果async-->sync开始出现错误,则会给我们一个瓶颈)

那么,你的例子呢 在您的示例中,假设您有一个非异步函数。在该函数中,您需要调用wait webClient.DoSomethingAsync()。您不能在非异步的函数中调用wait,编译器不会允许您这样做

选项1:僵尸侵扰

您的第一个选择是一路爬网备份您的调用堆栈,将沿途的每个da*n方法标记为async,并在任何地方等待添加。到处都是。就像,到处都是。然后——因为所有这些方法现在都是异步的,所以需要使引用它们的方法都是异步的

顺便说一句,这可能是许多如此狂热的人要提倡的方法。因为,“阻止线程是个坏主意。”

所以。是 啊这种“让异步变为异步”的方法意味着您的小型库例程只需接触到json对象并触及80%的代码。谁给CTO打电话让他知道

选项2:只需选择一个僵尸即可

或者,您可以将您的异步封装在类似您的函数中

return Task.Run(async () => {
     content = await new WebClient().DoSomethingAsync();
     cachedDownloads.TryAdd(address, content);
     return content;
});
普雷斯托。。。僵尸感染已经包含在一段代码中。我将让位机制来讨论如何/为什么在CPU级别执行。我真的不在乎。我关心的是,没有人必须向CTO解释为什么整个库现在应该是100%异步的(或者类似的)

在Task.Run()中使用async/await有什么好处吗

您还可以问相反的问题:为什么要在Task.Run中包装异步/等待代码

一个异步方法在第一个等待被点击时(对未完成的任务进行操作)就返回给调用者。因此,如果异步方法的第一次执行“streak”需要很长时间,则Task.Run将改变行为:它将导致该方法立即返回并在线程池上执行第一次“streak”

这在UI场景中很有用,因为这样可以100%确保没有阻塞UI。示例:
HttpWebRequest
即使在使用一种异步方法时也会同步进行DNS解析(这基本上是一个库错误/设计错误)。这可能会暂停UI线程。因此,您可以使用Task.Run 100%确保UI的阻塞时间不会超过几微秒


那么回到原来的问题:为什么要在任务中等待呢?出于同样的原因,您通常会等待:解锁线程。

@DavidBS不使用
Wait
阻止
任务
,这是一种简单的死锁方法。在这种情况下,您不需要
任务。请运行
。您只需要
var result=wait new WebClient().downloadstringtaskancy(“”)
DownloadStringTaskAsync
已经是一个异步操作。@KosalaW,看看链接的代码,它正在执行一个块,如果它没有包装在任务中,可能会死锁。@FilipEkberg刚刚看到了它。对这是一个有效的例子。@Chandan如果您不希望该方法实际上是异步的,那么就不要使用异步IO方法。如果您想同步地完成工作,只需使用同一类中的同步模拟即可。要么异步执行所有操作,要么不异步执行任何操作。不要半途而废;它给了你两个世界中最糟糕的。CTO会关心你的异步代码吗?;)有“最佳实践”可供选择
return Task.Run(async () =>
{
    content = await new WebClient().DownloadStringTaskAsync(address);
    cachedDownloads.TryAdd(address, content);
    return content;
});
return Task.Run(async () => {
     content = await new WebClient().DoSomethingAsync();
     cachedDownloads.TryAdd(address, content);
     return content;
});