我有一个简单的异步程序并等待:
class Program
{
static void Main()
{
var demo = new AsyncAwaitDemo();
Task.Run(() => {demo.DoStuff()};
while (true)
{
Console.WriteLine("Doing Stuff on the Main Thread...................");
}
}
}
public class AsyncAwaitDemo
{
public async Task DoStuff()
{
await LongRunningOperation();
}
private static async Task<string> LongRunningOperation()
{
int counter;
for (counter = 0; counter < 50000; counter++)
{
Console.WriteLine(counter);
}
return "Counter = " + counter;
}
}
我的第一个问题是:
Task.Run
,因为我刚删除并且程序变得同步。我知道这样的事实: await用于创建挂起点,并且在等待该函数的等待函数完成之前不会进一步执行。其次,
以下代码创建了多少个线程?
Task.Run(()=&gt; {demo.DoStuff()};
如果它多于一个,那么是依赖于内部操作的线程数,在本例中它是带有计数器的循环。
我开始理解C#中的异步编程,阅读并练习了几个样本。我能够将上下文与我上面提到的澄清区分开来。
答案 0 :(得分:3)
async
/ await
与Task.Run
无关;但是,它们在某些情况下确实可以很好地协同工作。
Task.Run
在线程池线程上运行一些代码。 async
/ await
是一种代码转换,允许您以更自然,更强制的方式编写异步代码(有关async
如何工作的详细信息,请参阅我的async
intro)。
是否必须在任何async和await方法中使用Task.Run,因为我刚删除并且程序变得同步。
完全没有! async
/ await
非常通常在没有Task.Run
的情况下使用。只要您拥有真正的异步操作,就可以使用async
/ await
。一般来说,任何基于I / O的东西都是自然异步操作的一个很好的例子。因此,您可以仅使用HttpClient.GetStringAsync
/ async
而不使用任何await
来使用Task.Run
之类的内容。
但请注意,使用async
而不使用await
几乎总是错误的。编译器会向LongRunningOperation
发出警告,通知您它实际上并非异步。
以下代码创建了多少个线程? Task.Run(()=&gt; {demo.DoStuff()};
该代码只将DoStuff
排队到线程池。线程池线程将执行DoStuff
。线程创建取决于许多其他因素。