【问题标题】:Task finishes before expected任务提前完成
【发布时间】:2015-06-14 09:54:09
【问题描述】:

我有这个方法: 私有静态异步任务 MyMethod(); 它是这样调用的:

public static void Main()
{
s_Finishing = false;
Task printTask = PrintStatistics();
MyMethod(serversSawa, serversSterling).Wait();
s_Finishing = true;
}

我希望 PrintStatistics 仅在 MyMethod 完成后才会停止运行。但不幸的是它没有。如果我评论行 s_Finishing = true; 任务将永远运行 - 并允许 MyMethod 完成 我该如何解决这个问题?

private static async Task PrintStatistics()
            {
                while (!s_Finishing)
                {
                    long total = 0;
                    await Task.Delay(TimeSpan.FromSeconds(20));
                    foreach (var statistic in s_Statistics)
                    {
                        ToolsTracer.Trace("{0}:{1}", statistic.Key, statistic.Value);
                        total += statistic.Value;
                    }

                    foreach (var statistic in s_StatisticsRegion)
                    {
                        ToolsTracer.Trace("{0}:{1}", statistic.Key, statistic.Value);
                    }

                    ToolsTracer.Trace("TOTAL:{0}", total);
                    ToolsTracer.Trace("TIME:{0}", s_StopWatch.Elapsed);
                }
            }
private static async Task MyMethod()
{
Parallel.ForEach(
                        data,
                        new ParallelOptions { MaxDegreeOfParallelism = 20 }, async serverAndCluster =>
                        {
                            await someMethod()                        });
}

【问题讨论】:

  • 永远不要在其他线程之外使用变量。所以你不应该让两个线程都访问一个全局变量

标签: c# task


【解决方案1】:

我相信你的问题就在这里:

Parallel.ForEach(..., async ...);

您不能将asyncForEach 一起使用。 需要以相同的方法同时执行并行(CPU 绑定)和async(I/O 绑定)是非常罕见的。如果您只想要并发(我怀疑),请使用Task.WhenAll 而不是ForEach。如果您确实需要 CPU 并行性和async,请使用 TPL 数据流。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    相关资源
    最近更新 更多