异步任务C#

时间:2018-11-05 15:48:55

标签: c# asynchronous

我试图了解C#中的异步编程。我创建了一个只能调用一次的函数示例。例如,从大文件读取。我想创建一个查询,请求将在查询中等待,直到他们可以安全地读取文件为止。

AsyncWork aw = new AsyncWork();

Task.Run(() => {
    for (int count = 0; count < 10; count++) {
        aw.DoAsyncWork(count);
        Console.WriteLine("request added");
    }
});
Console.ReadKey();

AsyncWork

public class AsyncWork {
    int Requests = 0;
    int Workers = 0;

    public AsyncWork() { }

    public async Task DoAsyncWork(int count) {
        Requests++;

        while (Workers > 0) ;

        Workers++;
        Requests--;

        if (Workers > 1) Console.WriteLine("MORE WORKERS AT ONCE");

        Console.WriteLine(count.ToString() + " Started task");
        //reading from file
        await Task.Delay(1000);
        Console.WriteLine(count.ToString() + " Ended task");

        Workers--;
    }
}

我希望我会有10个请求,然后一个接一个地完成。但是输出就像:

0 Started task
request added
0 Ended task
1 Started task
request added
1 Ended task
2 Started task
request added
2 Ended task
3 Started task
request added
3 Ended task
4 Started task
request added
4 Ended task
5 Started task
request added
5 Ended task
6 Started task
request added
6 Ended task
7 Started task
request added
7 Ended task
8 Started task
request added
8 Ended task
9 Started task
request added
9 Ended task

为什么它同步运行?

1 个答案:

答案 0 :(得分:4)

运行代码时,第一个工作程序将开始工作,然后下一个工作程序将陷入您while (Workers > 0) ;的繁忙循环中,并且直到前一个工作程序完成后才继续进行。然后,在启动工作程序时,下一个工作程序将在其中停留,依此类推,直到循环的每个迭代。

因此,您最多只能有一个工人在工作,而一个工人将整个CPU固定在那里等待它完成。

编写异步代码时同步访问的一种正确方法是使用SemaphoreSlim并使用WaitAsync,这将异步等待直到可以获取信号量,而不是同步阻塞线程(并在占用线程时固定CPU),以供其他工作人员完成。它也具有可以安全地从多个线程访问的优点,这与整数 不能从多个线程进行更改不同。