【问题标题】:C# winforms app thread synchronizationC# winforms 应用线程同步
【发布时间】:2013-04-16 22:34:59
【问题描述】:

我是编程的初学者,我想知道同步线程。

我有一个 WinForms 程序,它需要为每个 cpu 内核创建线程并运行一个方法指定的次数。

我在嵌套循环中设置和运行线程,但我的输出是这样的;

thread: 0, run: 1, time: xxx
thread: 1, run: 1, time: xxx
thread: 2, run: 1, time: xxx
thread: 3, run: 1, time: xxx
thread: 1, run: 2, time: xxx
thread: 2, run: 2, time: xxx

等等。但是我希望输出像这样显示数据:

thread: 0, run: 1, time: xxx
thread: 0, run: 2, time: xxx
thread: 0, run: 3, time: xxx
thread: 1, run: 1, time: xxx
thread: 1, run: 2, time: xxx
thread: 1, run: 3, time: xxx

等等

在我的表单中,我创建线程并从一个单独的类中调用一个方法,就像这样;

SomeClass[] thisArray = new SomeClass[numThreads];

for (int runNumber = 1; runNumber <= numberOfRuns; runNumber++)
    {
        for (int i = 0; i < numThreads; i++)
        {
            thisArray[i].mThread = new Thread(thisArray[i].StartMethod);
            thisArray[i].mThread.Start();
            thisArray[i].mThread.Join();


           //Display thread id and number of runs
           this.tBoxW.AppendText(string.Format("") + Environment.NewLine);
           this.tBoxW.AppendText(string.Format("Thread Id: ") + i.ToString() + 
           Environment.NewLine);

           this.tBoxW.AppendText(string.Format("Number of Runs {0}", numberOfRuns) + 
           Environment.NewLine);

        }
}

SomeClass 位于 SomeClass.cs 中,并提供 StartMethod() 方法,该方法通过一系列方程运行。

为了以我想要的方式获得输出,我是否正确地假设我需要同步线程?或者也许有更简单的方法?

由于我刚开始使用线程,我正在寻找实现所需输出的最简单方法。

任何帮助将不胜感激。感谢您花时间查看我的问题。

【问题讨论】:

  • 启动一个线程然后调用 Join() 是没有意义的。您不妨直接调用 StartMethod() 。仅在循环外加入 Join()。
  • 谢谢汉斯,我会试试这个
  • @Hans Passant:是的,这基本上使他的解决方案连续

标签: c# multithreading synchronization


【解决方案1】:

我不清楚你想要什么。您必须告诉我们更多您的问题需要什么同步。线程任务如何相互依赖?如果它们依赖,您必须同步。最后还是要同步。

由于它是 WinForms,我不确定它是否可行(无论您是否绑定到较旧的 .NET 版本),但请尝试使用较新的 Task API。然后你可以 WaitAny()。或者,如果您可以将问题转换为并行循环,那就更好了。

另外,您在谈论 CPU 内核。您将无法将线程显式分配给某些 CPU 内核(也许 99% 的情况下甚至不建议这样做)。线程池会处理这个问题。如果您需要耗尽所有 CPU 资源,您可能希望生成比 CPU 更多的线程。

【讨论】:

  • 感谢 Csaba 的建议,我不关心使用哪种类型的同步,但我认为监视器的开销比传统的互斥锁或信号量少吗?该程序使用.net 4.0 框架。我将研究 Task API,看看我是否可以做任何事情。我真的只是希望输出显示每个线程一次运行一个,而不是在运行完成后立即显示信息,无论它是哪个线程。
  • 好的,所以你想要并发,但你想要看到一个排序的输出。在这种情况下,您必须收集输出,为自己排序并显示它。如果您只想在最后显示它,那就更容易了。如果您想在输出中显示它的排序,那么这就不那么简单了。你需要跟踪任务的输出,如果有差距,你必须坚持输出,直到差距被填补。这就是 VS2012 的“构建顺序”输出所做的。 VS2012后面有并行构建系统,输出可以混用。 Build Order 按顺序显示,但这可能会导致“输出爆发”
  • 再次感谢 Csaba,我只需要在最后显示输出,所以我采纳了您的建议,我能够通过创建列表对象数组对输出进行排序。它不漂亮,但该死的,它有效!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 2011-06-15
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多