Tir*_*ran 2 c# multithreading asynchronous
我想了解异步和等待的工作原理,所以我编写了这个小程序来尝试在“a”之前打印“b”,但它不起作用,我无法弄清楚......有什么帮助吗?:)
public class program
{
static async Task Main()
{
await a();
b();
}
async static Task a()
{
Console.WriteLine("Waiting for a");
for (int i = 0; i < 100000000; i++)
if (i % 1000000 == 0)
Console.Write(".");
Console.WriteLine("\na");
}
static void b()
{
Console.WriteLine("b");
}
}
Run Code Online (Sandbox Code Playgroud)
让我们完善您的代码。首先它不起作用,因为你告诉代码await a(),所以该行之后的任何内容都不能在它之前(或期间)运行。让我们修复它:
static async Task Main()
{
var task = a();
b();
await task;
}
Run Code Online (Sandbox Code Playgroud)
但这还不够,它仍然不起作用。a()它仍然在之前运行,b()因为您的a方法不是异步的。事实上它是同步的。仅仅因为您使用async/await它并不会使代码自动异步。你需要的还不止这些。一种方法是添加await Task.Yield()真正的异步调用,即使它不执行任何操作(除了允许发生切换)。像这样:
async static Task a()
{
Console.WriteLine("Waiting for a");
for (int i = 0; i < 100000000; i++)
if (i % 1000000 == 0)
{
Console.Write(".");
await Task.Yield();
}
Console.WriteLine("\na");
}
Run Code Online (Sandbox Code Playgroud)
现在您将看到b()在 的中间运行a()。您可以尝试一下该await Task.Yield();调用,并将其放在不同的位置以查看不同的结果。
这仍然是一个有点原始的例子。最好b()也做成异步的。并使用延迟。像这样:
public class program
{
static async Task Main()
{
var task1 = a();
var task2 = b();
await task1;
await task2;
}
async static Task a()
{
Console.WriteLine("Waiting for a");
for (var i = 0; i < 100; i++)
{
Console.Write(".");
await Task.Delay(20);
}
Console.WriteLine("\na");
}
static async Task b()
{
await Task.Delay(200);
Console.WriteLine("b");
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我稍微修改了你的a(),以便它更多地依赖于时间,更少地依赖于 CPU 速度。
当然,您现在遇到了线程安全问题,在本例中这是可以的,因为Console方法Task是线程安全的。但通常您必须意识到,当两个或多个任务同时运行时,它们可能在不同的线程上运行,因此您必须使代码线程安全。
| 归档时间: |
|
| 查看次数: |
886 次 |
| 最近记录: |