Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.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# UI线程在不应';不可能_C#_.net_Wpf_Multithreading - Fatal编程技术网

C# UI线程在不应';不可能

C# UI线程在不应';不可能,c#,.net,wpf,multithreading,C#,.net,Wpf,Multithreading,在WPF应用程序(C#,.NET 4.0,VS 2013)中,以下代码(从UI线程调用)将UI线程冻结1秒: new Thread(new ThreadStart(() => { Dispatcher.BeginInvoke(new Action(() => { Thread.Sleep(1000); })); })).Start(); Thread.Sleep()是一个占位符。在实际代码中,它将访问一些UI元素并进行一些耗时的计算。这也在U

在WPF应用程序(C#,.NET 4.0,VS 2013)中,以下代码(从UI线程调用)将UI线程冻结1秒:

new Thread(new ThreadStart(() =>
{
    Dispatcher.BeginInvoke(new Action(() =>
    {
        Thread.Sleep(1000);
    }));
})).Start();
Thread.Sleep()
是一个占位符。在实际代码中,它将访问一些UI元素并进行一些耗时的计算。这也在UI线程上运行


它不应该在UI线程以外的其他线程中运行吗?我错过了什么?

调度程序。BeginInvoke设计用于将操作(通过代理)推送到UI线程上。您已经告诉它将
线程。Sleep(1000)
推到UI线程上,所以是的:UI线程将冻结

例如,从主UI线程派生的后台线程无法更新在UI线程上创建的按钮的内容。为了让后台线程访问按钮的内容属性,后台线程必须将工作委托给与UI线程关联的调度程序。这是通过使用Invoke或BeginInvoke来实现的。Invoke是同步的,BeginInvoke是异步的

如果你想在后台工作。。。您已经在后台线程上(在调用
Dispatcher.BeginInvoke
之前)

我想你应该在这里做的是:

  • 使用
    .Invoke
    将值从UI收集到worker中
  • 对工人进行处理
  • 使用
    .Invoke
    .BeginInvoke
    更新UI

  • Dispatcher.BeginInvoke
    设计用于将操作(通过委托)推送到UI线程上。您已经告诉它将
    线程。Sleep(1000)
    推到UI线程上,所以是的:UI线程将冻结

    例如,从主UI线程派生的后台线程无法更新在UI线程上创建的按钮的内容。为了让后台线程访问按钮的内容属性,后台线程必须将工作委托给与UI线程关联的调度程序。这是通过使用Invoke或BeginInvoke来实现的。Invoke是同步的,BeginInvoke是异步的

    如果你想在后台工作。。。您已经在后台线程上(在调用
    Dispatcher.BeginInvoke
    之前)

    我想你应该在这里做的是:

  • 使用
    .Invoke
    将值从UI收集到worker中
  • 对工人进行处理
  • 使用
    .Invoke
    .BeginInvoke
    更新UI

  • Dispatcher.BeginInvoke在主线程上执行操作。使用此选项在线程上执行:

        new Thread(new ThreadStart(() =>
        {
            {
                Thread.Sleep(1000);
            };
        })).Start();
    

    Dispatcher.BeginInvoke在主线程上执行操作。使用此选项在线程上执行:

        new Thread(new ThreadStart(() =>
        {
            {
                Thread.Sleep(1000);
            };
        })).Start();
    

    就像Marc已经说过的那样,Dispatcher.BeginInvoke()将操作中的所有代码推送到UI线程,以便在那里执行代码。如果希望UI保持响应,请在调用Dispatcher之前进行计算。开始调用,然后在BeginInvoke中设置UI控件

    new Thread(new ThreadStart(() =>
    {
        int result = MyHeavyCalculation();
        Dispatcher.BeginInvoke(new Action(() =>
        {
            label1.Text = result.ToString();
        }));
    })).Start();
    

    或者看看如何异步执行方法,而不用自己操心UI线程同步

    就像Marc已经说过的那样,Dispatcher.BeginInvoke()将操作中的所有代码推送到UI线程,以便在那里执行代码。如果希望UI保持响应,请在调用Dispatcher之前进行计算。开始调用,然后在BeginInvoke中设置UI控件

    new Thread(new ThreadStart(() =>
    {
        int result = MyHeavyCalculation();
        Dispatcher.BeginInvoke(new Action(() =>
        {
            label1.Text = result.ToString();
        }));
    })).Start();
    

    或者看看如何异步执行方法,而不用自己操心UI线程同步

    您正在使用dispatcher在UI线程上执行操作,它会阻塞一秒钟。请注意,从后台线程访问UI将导致异常。必须在主线程上更新UI元素,为此,您可以使用Dispatcher.BeginInvoke(…)。您正在使用Dispatcher在UI线程上执行操作,它会阻塞一秒钟。请注意,从后台线程访问UI将导致异常。UI元素的更新必须在主线程上完成,为此,您可以使用Dispatcher.BeginInvoke(…)。谢谢。我倾向于忘记Dispatcher.BeginInvoke/Invoke的用途:(谢谢。我倾向于忘记Dispatcher.BeginInvoke/Invoke的用途:(