2014-12-24 36 views
0

有谁知道为什么这段代码是减慢UI:线程中运行一个沉重的方法是减慢C#中的UI

Thread trdGenerateTrajectory = new Thread(() => HeavyMethod()); 
trdGenerateTrajectory.Start(); 
trdGenerateTrajectory.Join(); 

这应该是比主线程一个单独的线程,我是对?如果是这样,为什么运行它会减慢/冻结UL?

编辑:感谢您的意见。我删除了Join(),但它仍冻结了UI。任何想法?

更新:HeavyMethod()方法从我创建的Matlab dll调用一个方法。 dll中的方法为机器人生成操纵轨迹。我的项目是一个重型机器人项目,可以与很多硬件/设备进行通信。该项目有12名背景工人和一名计时员。计时器负责更新UI和所有文本/颜色/图像/ ...。到目前为止,我对背景工作者和计时器没有任何问题,无论他们正在运行的任务有多重,我从来没有看到任何延迟或停止计时器和UI更新。但是,当我在Matlab dll中调用这个特定的方法时,我看到在更新UI之前看到一个完整的停止,直到方法完成。这是我所经历的:

  1. 我用线程(上面的代码)没有运气。
  2. 然后,我将运行方法后的方法和过程移到另一个背景工作器中,再次没有运气。

然后我意识到,我的表单上的一些文本框正在遇到这个问题。他们是那些从相同的Matlab DLL的另一种方法获得他们的价值观。那时我意识到这个问题与线程/背景工作者没有任何关系,并且与Matlab运行方法的方式有关。也许它是单线程的!?无论如何,如果我为这种生成轨迹的特定方法制作单独的dll,可能会有所帮助,所以我创建了另一个dll,但我遇到了完全相同的问题。看起来像Matlab DLL一次只能运行一种方法,不管你是从不同的线程还是从单独的dll调用它们。我相信我应该在单独的SO问题中提出这个问题,而且我会,但同时,你对此有何评论? (更新:我没有收到任何回复,所以我发布了一个新问题:Calling two functions from a single Matlab dll at the same time

+1

使用您cpusets - 并且是一个多核系统上的代码? –

+0

异步与同步,调度程序线程等等可以帮助您。你创建了一个线程怎么样以及何时运行它。当UI线程运行时会发生什么?是否有进度条正在运行? – Gilad

+0

这是什么类型的程序? Windows窗体? –

回答

6

尽管您正在后台线程上运行计算,但您的UI线程仍会阻止您的UI线程,直到您的计算完成。

今天这样做的正确方法是使用asyncawait关键字。如果你真的想自己限制线程,你可以使用线程内的Invoke呼叫调度指挥回到UI线程一旦计算完成:

Thread trdGenerateTrajectory = new Thread(() => 
{ 
    HeavyMethod(); 

    this.Invoke(new Action(() => 
    { 
     // Update UI here. 
    })); 
}); 

trdGenerateTrajectory.Start(); 
// trdGenerateTrajectory.Join(); <- do not block 

编辑:假设你想运行在回应一些按钮,点击(或任何其他活动)的计算,可以使用异步模式在事件处理程序,如下所示:

private async void myButton_Click() 
{ 
    await Task.Run(HeavyMethod); 

    // Update UI here. 
} 
+0

谢谢,你能告诉我如何使用异步并等待解决这个问题吗? – NESHOM

+0

@NESHOM:更新了答案。 – Douglas

+0

谢谢。我尝试了没有Join()的简单代码。它仍然冻结用户界面。你有什么想法是什么原因? – NESHOM

4

您正在启动线程并立即加入它。加入线程意味着您正在等待它结束。

通常,用户界面是单线程的。这意味着您的方法需要返回另一个要处理的事件。

+0

HeavyMethod()正在生成一些数据。这意味着我需要在线程完成后立即处理数据。我正在尝试使用类似于BackgroundWorker的DoWork()方法,但只使用线程。可能吗?我相信如果我将HeavyMethod()方法移动到背景工作,它不会减慢UI,对吗? – NESHOM

+0

您可以随时在'HeavyMethod()'调用后的lambda中进行处理,并移除对“Join()'的调用。 –

相关问题