Task.WhenAny在任务完成时不存在

问题描述 投票:0回答:1

我们有一个逻辑,可以让后台作业每20分钟运行一次,或者在完成任务后继续运行。

我想做的简化版如下:

控制是否需要退出的任务:

private static TaskCompletionSource<bool> forceSyncTask = new TaskCompletionSource<bool>();

后台工作:

     Task.Factory.StartNew(
                async () =>
                {
                    do
                    {
                        await Dosomething();
                        await Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(20)), forceSyncTask.Task);

                        // Always reset the force sync property
                        forceSyncTask = new TaskCompletionSource<bool>();
                    }
                    while (true);
                });

然后每当有通知到来时,我运行以下命令强制退出Task.WhenAny

    if (!forceSyncTask.Task.IsCompleted)
    {
        forceSyncTask.TrySetResult(true);
    }

我在开发框中对其进行了测试,并且可以正常工作。但是,在将其部署到产品环境中的Webervice之后,即使我成功完成SetResult(我已记录下来知道TrySetResult是否返回true),Task.WhenAny也不会按预期退出。

任何人都知道为什么吗?

c# multithreading async-await static
1个回答
0
投票

首先,我建议您使用已建立的解决方案来暂停异步方法,例如Stephen Toub's PauseTokenPauseToken。当前代码中有一些危险信号:PauseToken from my AsyncEx library,并且不带PauseToken选项的情况下使用StartNew with an async delegate and without a TaskScheduler。最好坚持使用较高级别的结构(分别为StartNewasync),因为低级结构上有很多尖角。

就确切的问题而言,这很难说,特别是因为您(和我们)无法在本地复制它。这是我的最高猜测:

  1. [您遇到了TaskScheduler-即TaskCompletionSource<T>最终直接调用RunContinuationsAsynchronously中的某些代码而导致的问题。
  2. 您在生产服务器上遇到线程耗尽。
© www.soinside.com 2019 - 2024. All rights reserved.