【问题标题】:Tasks are running sequentially for some reason由于某种原因,任务按顺序运行
【发布时间】:2013-03-26 06:46:44
【问题描述】:

案例 1:我有一个控制台测试应用程序和库。测试应用程序对那些打算并行运行的库中的类调用异步方法。示例代码

        for (int i = 0; i < 100; i++)
        {
            var myTask = RetrieveRecordSet<TestClass3>();
        }

这在控制台应用程序中按预期工作,这意味着所有 100 个任务同时排队,并且这些任务在后台并行执行,其控制台输出证明了这一点。

案例 2:相同的代码,只是在 WPF 应用程序而不是控制台应用程序中。现在由于某种原因,任务按顺序运行。

案例 3:我也尝试对 WPF 应用进行以下修改,但无济于事:

        for (int i = 0; i < 100; i++)
        {
            var myTask = Task.Factory.StartNew(() => RetrieveRecordSet<TestClass3>());
        }

案例 4:然后我尝试了以下操作,但它阻塞了 UI 并且仍然是连续的

        Parallel.For(0, 100, a => RetrieveRecordSet<TestClass3>());

有没有办法在 WPF 应用程序中获得与案例 1 相同的非阻塞并行行为?

【问题讨论】:

  • RetrieveRecordSet 是如何工作的?显示它如何启动任务以及任务的外观。正在运行的任务会占用线程吗?

标签: c# parallel-processing


【解决方案1】:

尝试以下方法:

Await Task.Run(() => 
{
    Parallel.For(0,100, ()=> RetrieveRecordSet<>());
}

【讨论】:

    【解决方案2】:

    Parallel.For 确实是一个阻塞操作。如果您希望 Parallel.For 循环在与 UI 不同的线程上运行:

    new Thread(() => Parallel.For(0, 100, index => RetrieveRecordSet<TestClass3>())).Start();
    

    或者

    new Task(() => Parallel.For(0, 100, index => RetrieveRecordSet<TestClass3>())).Start();
    

    【讨论】:

      【解决方案3】:

      感谢各位的回答。最后,答案更加邪恶,我仍然不确定问题是什么,但我找到了解决方法。底层代码正在进行 WCF 服务调用。第一次使用通道时,使用任务并行库进行一堆并行 WCF 调用,将序列化这些调用。我偶然发现,如果你先用一个调用“启动”通道,等待响应,然后用一堆并行的 WCF 调用猛击它,你就会得到完全的并行性。是否有一种不那么老套的方式来启动 WCF 频道?这是 WCF 还是 TPL 中的错误?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-04
        • 2017-03-20
        • 2018-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多