c# - 为什么 Task.WhenAll 不工作?

标签 c# .net concurrency task

这是我正在使用的一些代码,它触发了三个任务。 My Stop 被调用,从输出来看,任务似乎在 Stop 返回后完成,这不是我所期望的。

这是带有 .NET 4.5.1 的 Visual Studio 2013

我使用 AutoResetEvent 进行了相同的尝试,结果按预期工作。

这是这个的输出:

Three tasks without auto reset
Starting...
FIRST
SECOND
THIRD
Running...
FIRST
FIRST
FIRST
SECOND
FIRST
FIRST
THIRD
...
SECOND
FIRST
Stopping...
THIRD
All done!
First done
Second done
Third done

我希望看到的是:

First done
Second done
Third done
All done!

这是代码(我什至在控制台输出周围添加了锁定,但没有任何区别):

public class ThreeTasksWithoutAutoResetEvent
{
    private CancellationTokenSource cancellation;

    private Task[] tasks;

    private object obj = new object();

    public ThreeTasksWithoutAutoResetEvent()
    {
        Console.WriteLine("Three tasks without auto reset");

        cancellation = new CancellationTokenSource();

        tasks = new Task[3];

        Message("Starting...");

        Start();

        Message("Running...");

        Thread.Sleep(3000);

        Message("Stopping...");

        Stop();

        Message("All done!");
    }

    private void Start()
    {
        tasks[0] = this.First(cancellation.Token);
        tasks[1] = this.Second(cancellation.Token);
        tasks[2] = this.Third(cancellation.Token);
    }

    private async void Stop()
    {
        cancellation.Cancel();

        await Task.WhenAll(tasks);
    }

    private async Task First(CancellationToken token)
    {
        await Task.Run(
            () =>
            {
                while (!token.IsCancellationRequested)
                {
                    Message("FIRST");
                    Thread.Sleep(100);
                }

                Message("First done");
            }, token);
    }

    private async Task Second(CancellationToken token)
    {
        await Task.Run(
            () =>
            {
                while (!token.IsCancellationRequested)
                {
                    Message("SECOND");
                    Thread.Sleep(300);
                }

                Message("Second done");
            }, token);
    }

    private async Task Third(CancellationToken token)
    {
        await Task.Run(
            () =>
            {
                while (!token.IsCancellationRequested)
                {
                    Message("THIRD");
                    Thread.Sleep(500);
                }

                Message("Third done");
            }, token);
    }

    private void Message(string message)
    {
        lock (obj)
        {
            Console.WriteLine(message);
        }
    }
}

最佳答案

因为您没有等待 Stop 方法完成。您不能等待 async void 方法。您需要返回一个任务,以便调用者可以等待/等待它完成。

private Task Stop()
{
    cancellation.Cancel();

    return Task.WhenAll(tasks);
}

然后您可以调用 Stop().Wait(); 而不是 Stop。这将等待 WhenAll 完成。

关于c# - 为什么 Task.WhenAll 不工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32987597/

相关文章:

c# - %LOCALAPPDATA% 在 app.config 中不起作用

c# - 与当前连接关联的事务已完成但尚未处理。 (编辑#3)

c# - RadGrid 底部的水平滚动空白

c++ - 功能/不可变数据结构在非垃圾收集上下文中是否仍然对并发有用?

python - 如何防止对USB设备等资源的并发访问?

c# - CLR 如何处理配置设置

c# - 保护我的代码免受逆向工程

c# - 无法获取 RowUpdate 事件处理程序以显示 GridView 的错误

.net - 相对 url 到新的完整 url

sql-server - 无法在快照隔离模式下使用 READPAST