yeg*_*gor 2 c# asynchronous async-await
我正在学习异步和等待在编程中如何工作。我在互联网上看到这个例子,说这是异步代码:
class Program
{
static async Task Main(string[] args)
{
Method2();
var count = await Method1();
Method3(count);
Console.ReadKey();
}
static async Task<int> Method1()
{
int count = 0;
await Task.Run(() =>
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine(" Method 1");
count += 1;
}
});
return count;
}
static void Method2()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine(" Method 2");
}
}
static void Method3(int count)
{
Console.WriteLine("Total count is " + count);
}
}
Run Code Online (Sandbox Code Playgroud)
据我了解,异步编程是并发编程的一种形式,它允许两个单独的代码同时运行。但所有这些等待运算符使代码运行一致,实际上,我们可以使用以下示例,它给出相同的输出:
class Program
{
static async Task Main(string[] args)
{
Method2();
Method3(Method1());
Console.ReadKey();
}
static int Method1()
{
int count = 0;
for (int i = 0; i < 3; i++)
{
Console.WriteLine(" Method 1");
count += 1;
}
return count;
}
static void Method2()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine(" Method 2");
}
}
static void Method3(int count)
{
Console.WriteLine("Total count is " + count);
}
}
Run Code Online (Sandbox Code Playgroud)
那么,为什么我要使用await 运算符,因为它们本质上使异步代码同步呢?
我在互联网上看到这个例子,说这是异步代码
有点。这就是我所说的“假异步”:代码用于await Task.Run异步等待线程池线程完成的同步工作。这与“真正的异步”形成对比,“真正的异步”通常是 I/O(即,没有线程池线程等待操作完成)。不过,“假”异步并不意味着它是坏的;它非常适合 UI 应用程序。
据我了解,异步编程是并发编程的一种形式,它允许两个单独的代码同时运行。
我想说并发编程是同时运行单独的代码片段。然后有两种不同类型的并发编程:并行和异步。并行性使用多个线程并发运行;异步使用非阻塞方法来并发运行。
关键要点是异步不会阻塞调用线程。其目的是释放线程。
所以,回到“假异步”:从一个角度来看,是的,它是异步的,因为它不会阻塞调用线程。但我称其为“假异步”,因为它会阻塞线程池线程以释放调用线程。同样,在某些情况下这完全没问题,例如,如果调用线程是 UI 线程并且您希望保持 UI 响应。
但是所有这些await 运算符都使代码运行一致......那么,当await 运算符本质上使异步代码同步时,为什么我要使用await 运算符呢?
我相信您正在寻找的术语是“串行”,它经常与“同步”混淆。串行代码一次运行一个。在您发布的示例中,使用了一种非常常见的模式:
var count = await Method1();
Run Code Online (Sandbox Code Playgroud)
因此,Method1启动并返回(这是异步代码,因此在完成之前Method1返回 a ;已返回的将在完成时完成)。然后调用线程立即执行.Task TaskMethod1await
这是一种非常常见的模式,用于确保进度被序列化:我们不想Main继续执行,直到Method1完成并且我们可以将结果放入count.
然而,“串行”并不意味着“同步”。所有同步代码本质上都是串行的(您必须使用并行性来施加并发性)。大多数异步代码也是串行的。然而,它是异步串行的;调用线程没有被阻塞。在您的示例中,当到达其 时,将返回不完整,并且该线程被释放并且不会被 阻塞。MainTaskawaitMain
在控制台应用程序中很难看到这种好处。但如果该线程是 UI 线程,那么您的 UI 可以保持响应。如果该线程是 ASP.NET 线程池线程,那么它可以处理其他请求,从而提高服务器的可伸缩性(请注意,对于 ASP.NET 上的“假异步”而言,情况并非如此,只有“真异步”)。
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |