非常感谢帮助重新设计以下C#程序的想法。我试图在实现多线程之间选择使用1)TAP,2)包含微调的粗粒度线程,当它们的bool设置为false时终止,或3)使用信令而不是这些bool的相同线程。我将解释下面的程序,以便明确这个案例。
该计划
该程序是C#中的游戏自动化应用程序,我正在开发它作为一种有趣的方式来学习语言和更好的C#(5.0)功能。它有一个UI,需要在应用程序运行时保持响应。
当打开UI中的特定选项卡时,程序将启动一个名为" Scan"在另一个类的新方法中,使用UI的SynchronizationContext扫描各种内存位置并使用这些快速更改的值更新UI中的标签。只要扫描bool为真(通常是程序的整个生命周期),这会在一段时间(扫描)循环中继续进行。
当用户单击此选项卡上的“开始”按钮时,程序会激活两个执行以下操作的新线程:Thread" Run"沿着特定路径移动角色。线程"行动"点击特定按钮并在玩家运行路径的同时执行操作。如果发生某种情况,程序应该暂时停止正在运行的线程和操作线程,运行一个方法,当它完成时,返回到运行和操作。
当用户单击此选项卡上的“停止”按钮时,自动应该停止并且线程终止。
挑战
我已经在每个线程中使用连续的微调器循环创建了一个工作版本,负责各种工作。旋转器运行一段时间(myBool)。对于三个线程,bool是:扫描,运行和操作。
当我想停止一个线程时,我将bool设置为false,并使用Thread.Join等待线程优雅地终止,然后继续。如上所述,线程可以由用户单击“停止”按钮来停止,或者作为其功能的一部分由程序自动停止。在后一种情况下,线程停止,加入,然后在稍后阶段重新启动。
在对C#5.0中的线程和新的异步编程工具进行了大量的阅读和研究之后,我意识到我目前正在做的方式可能非常笨拙和不专业。它创建了许多同步/线程安全问题,并且所有这一切的目标是要了解更多有关C#的信息,我想了解是否应该将其更改为细粒度的异步编程方法,而不是使用TAP async并等待适当的。
这听起来像带有取消令牌的任务可能有用吗?所有线程都是长时间运行的操作,所以我担心使用线程池(Task.Run)会导致线程池中的不良卫生(超额预订)。如果异步编程在这里看起来像是一个糟糕的匹配,那么如何使用线程,而是使用信号来启动和停止线程?
任何想法都非常感激。
答案 0 :(得分:0)
没有。 TPL旨在运行较短的任务,其中新线程的分配始终会损害性能。它有很好的功能,如作业队列和工作窃取(TPL线程可以从另一个线程获取作业)。它当然可以有更长的运行任务,但你不会从中获得这么多的好处。相反,你强迫TPL分配新的线程。
但是,问题有点笼统,因为我们需要更多关于您实际实现的信息才能知道您应该使用什么。对于Scan线程来说,很明显它应该在一个线程中运行。
但对于其他人来说,很难知道。他们是一直在工作还是定期工作?如果他们一直在工作,你应该把它们分开。
至于线程同步,还有另一种选择。您可以使用ConcurrentQueue
排队必须绘制的所有内容。这样您就不需要任何同步。让UI线程检查队列并在其中绘制任何内容,而生产者可以继续工作。
事实上,通过这种方式,您可以将与UI绘图无关的任何内容移动到其他线程。这也应该可以提高应用程序的响应能力。
public void ActionRunnerThreadFunc()
{
_drawQueue.Enqueue(new SpaceShipRenderer(x, y));
}
public void UIThreadFunc()
{
IItemRender item;
if (_drawQueue.TryDequeue(out item))
item.Draw(drawContext);
}