Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 运行重载方法的线程正在减慢C中的UI_C#_Multithreading_User Interface_Freeze - Fatal编程技术网

C# 运行重载方法的线程正在减慢C中的UI

C# 运行重载方法的线程正在减慢C中的UI,c#,multithreading,user-interface,freeze,C#,Multithreading,User Interface,Freeze,有人知道为什么这段代码会减慢UI速度吗: Thread trdGenerateTrajectory = new Thread(() => HeavyMethod()); trdGenerateTrajectory.Start(); trdGenerateTrajectory.Join(); 这应该是在一个独立的线程比主线程,我说的对吗?如果是这样,为什么运行它会减慢/冻结UL 编辑:谢谢你的评论。我删除了Join,但它仍然冻结了UI。有什么想法吗 更新:HeavyMethod方法正在从我

有人知道为什么这段代码会减慢UI速度吗:

Thread trdGenerateTrajectory = new Thread(() => HeavyMethod());
trdGenerateTrajectory.Start();
trdGenerateTrajectory.Join();
这应该是在一个独立的线程比主线程,我说的对吗?如果是这样,为什么运行它会减慢/冻结UL

编辑:谢谢你的评论。我删除了Join,但它仍然冻结了UI。有什么想法吗

更新:HeavyMethod方法正在从我创建的MatlabDLL调用一个方法。dll中的方法生成机器人的操纵轨迹。我的项目是一个重型机器人项目,可以与许多硬件/设备进行通信。该项目有12名后台工作人员和一名定时器。计时器负责更新UI和所有文本/颜色/图像/。。。在上面。到目前为止,我对后台工作人员和计时器没有任何问题,无论他们执行的任务有多繁重,我从未看到计时器和UI更新有任何延迟或停止。然而,当我在MatlabDLL中调用这个特定的方法时,我看到UI上的一个句号正在更新,直到该方法完成。这就是我的经历:

我使用了上面代码中的线程,但运气不好。 然后,在运行该方法之后,我将该方法和流程移动到另一个backgroundworker中,同样没有运气。
然后我意识到我表单上的一些文本框遇到了这个问题。它们是从同一Matlab dll的另一种方法中获取其值的。那是我意识到这个问题与线程/后台工作人员无关的时候,它与Matlab的运行方法有关。也许它是单线程的!?无论如何,我认为如果我为这个生成轨迹的特定方法创建单独的dll可能会有所帮助,所以我创建了另一个dll,但我遇到了完全相同的问题。看起来MatlabDLL一次只能运行一个方法,不管您是从不同的线程调用它们,还是从单独的dll调用它们。我相信我应该在单独的SO问题中提出这个问题,我会的,但同时,你对此有何评论?更新:我没有收到任何回复,所以我发布了一个新问题:

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


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

尽管您在后台线程上运行计算,但您的Join调用仍会导致UI线程阻塞,直到计算完成

今天正确的方法是使用async和await关键字。如果您确实希望将自己限制为线程,则可以在计算完成后使用线程内的调用将控制权分派回UI线程:

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

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

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

您使用的是cpusets吗?代码是否在多核系统上?异步vs同步、调度程序线程以及其他许多功能都可以帮助您。您创建了一个线程,如何以及何时运行它。UI线程在运行时会发生什么?有进度条在运行吗?这是什么样的程序?Windows窗体?是的,它在8核系统上。我有一个计时器,可以更新文本框。当我运行上述代码时,文本框中的文本将停止更新,直到该线程完成。我的程序是Winform。如果您的UI在删除Join后仍处于阻塞状态,则HeavyMethod中的代码未正确使用主UI线程。也许你有一个调用?…重量级方法正在生成一些数据。这意味着我需要在线程完成后立即处理数据。我正在尝试一些类似于backgroundworkers的DoWork方法,但只是使用线程。可能吗?我相信如果我将HeavyMethod方法移动到backgroundworker,它不会降低UI的速度,对吗?在HeavyMethod调用后,您可以随时在lambda中进行处理并删除调用以加入。谢谢,您能告诉我如何使用async并等待解决此问题吗?@NESHOM:更新的答案。谢谢。我没有加入我的简单代码。它仍在冻结用户界面。你知道原因是什么吗?冻结UI是指你没有任何进度更新,还是说你的UI完全停止响应用户输入?如果是后者,那么正如Idle_Mind所说,您的重量级方法可能会在内部向UI线程发送一些调用。这甚至可能发生在你称之为图书馆的地方;例如,Office对象模型透明地运行UI线程上的所有调用。你能在你的问题中给我们一些关于HeavyMethod做什么的上下文吗?另一种可能性:你的HeavyMethod可能会通过子线程或任务产生更多的并行处理,从而使你的CPU使用率达到100%。因此,尽管UI线程是免费的,但操作系统很难为其分配一个可运行的内核。同样,这些只是猜测;如果你能给我们展示一个在重方法中发生的简单例子,那将是最好的。
private async void myButton_Click()
{
    await Task.Run(HeavyMethod);

    // Update UI here.
}