NES*_*HOM 0 c# user-interface multithreading freeze
有谁知道为什么这段代码会降低用户界面的速度:
Thread trdGenerateTrajectory = new Thread(() => HeavyMethod());
trdGenerateTrajectory.Start();
trdGenerateTrajectory.Join();
Run Code Online (Sandbox Code Playgroud)
这应该是在主线程的单独线程中,我是对的吗?如果是这样,为什么运行它会减慢/冻结UL?
编辑:感谢您的评论.我删除了Join(),但它仍然冻结了UI.任何的想法?
更新:HeavyMethod()方法从我创建的Matlab DLL调用方法.dll中的方法为机器人生成操纵轨迹.我的项目是一个重型机器人项目,与许多硬件/设备进行通信.该项目有12名背景工作者和一名计时器.计时器负责更新UI及其上的所有文本/颜色/图像/ .... 到目前为止,我还没有遇到任何与后台工作者和计时器有关的问题,无论他们运行的任务有多重,我都没有看到任何延迟或停止计时器和UI更新.但是,当我在Matlab dll中调用这个特定的方法时,我看到UI的完全停止正在更新,直到方法完成.这就是我的经历:
然后我意识到我的表单上只有一些文本框遇到了这个问题.他们是那些从同一个Matlab dll的另一个方法获取值的人.那时我才意识到这个问题与线程/后台工作者无关,而且与Matlab运行方法的方式有关.也许是单线程!?无论如何,我可能会有所帮助,如果我为这个生成轨迹的特定方法制作单独的dll,所以我创建了另一个dll,但我遇到了完全相同的问题.似乎Matlab dll一次只能运行一个方法,无论你是从不同的线程调用它们,还是从单独的dll调用它们.我相信我应该在另外的SO问题中提出这个问题,但是,在此期间,你对此有何评论?(更新:我没有收到任何回复所以我发布了一个新问题:同时从一个Matlab dll调用两个函数)
虽然您在后台线程上运行计算,但是您的Join调用会导致UI线程无论如何都会阻塞,直到计算完成为止.
今天这样做的正确方法是使用async和await关键字.如果您真的想将自己限制为线程,则可以Invoke在线程内使用调用,在计算完成后将控制权分派回UI线程:
Thread trdGenerateTrajectory = new Thread(() =>
{
HeavyMethod();
this.Invoke(new Action(() =>
{
// Update UI here.
}));
});
trdGenerateTrajectory.Start();
// trdGenerateTrajectory.Join(); <- do not block
Run Code Online (Sandbox Code Playgroud)
编辑:假设您要运行计算以响应某些按钮单击(或任何其他事件),您可以在事件处理程序中使用异步模式,如下所示:
private async void myButton_Click()
{
await Task.Run(HeavyMethod);
// Update UI here.
}
Run Code Online (Sandbox Code Playgroud)