Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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/6/xamarin/3.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#_Multithreading_Winforms - Fatal编程技术网

C# 从另一个线程更改控件文本的正确方法

C# 从另一个线程更改控件文本的正确方法,c#,multithreading,winforms,C#,Multithreading,Winforms,我有一个从5倒计时到0的线程: public static int seconds = 5; public static void startTimer() { Thread thread = new Thread(() => { while (seconds > 0) { Thread.Sleep(1

我有一个从5倒计时到0的线程:

public static int seconds = 5;
        public static void startTimer()
        {
            Thread thread = new Thread(() =>
            {
                while (seconds > 0)
                {
                    Thread.Sleep(1000);
                    seconds--;
                }                
            });
            thread.IsBackground = true;
            thread.Start();
        }
我想将标签“label1”的文本值更新到主窗体“Form1”上剩余的秒数

我目前正在线程中使用此选项:

Application.OpenForms["Form1"].Controls["label1"].Invoke(new Action(() => Application.OpenForms["Form1"].Controls["label1"].Text = str));
正确的做法是什么, 我需要为任务创建一个自定义线程


这种方式正确吗?如果不正确,我如何从线程引用label1的text属性。

您可以捕获正确的dispatcher并将其传递给线程,如下所示:

    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        var dispatcher = Dispatcher.CurrentDispatcher;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                dispatcher.Invoke(() => textBox1.Text = seconds.ToString());                                        
            }
        });
    }
    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        ISynchronizeInvoke invoker = this;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                Action updateMethod = () => textBox1.Text = seconds.ToString();
                invoker.Invoke(updateMethod, new object[] { });
            }
        });
    }
在没有调度程序的情况下,可以执行以下操作:

    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        var dispatcher = Dispatcher.CurrentDispatcher;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                dispatcher.Invoke(() => textBox1.Text = seconds.ToString());                                        
            }
        });
    }
    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        ISynchronizeInvoke invoker = this;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                Action updateMethod = () => textBox1.Text = seconds.ToString();
                invoker.Invoke(updateMethod, new object[] { });
            }
        });
    }

您可以捕获正确的dispatcher并将其传递给线程,如下所示:

    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        var dispatcher = Dispatcher.CurrentDispatcher;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                dispatcher.Invoke(() => textBox1.Text = seconds.ToString());                                        
            }
        });
    }
    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        ISynchronizeInvoke invoker = this;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                Action updateMethod = () => textBox1.Text = seconds.ToString();
                invoker.Invoke(updateMethod, new object[] { });
            }
        });
    }
在没有调度程序的情况下,可以执行以下操作:

    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        var dispatcher = Dispatcher.CurrentDispatcher;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                dispatcher.Invoke(() => textBox1.Text = seconds.ToString());                                        
            }
        });
    }
    private void button1_Click(object sender, EventArgs e)
    {
        int seconds = 5;

        ISynchronizeInvoke invoker = this;

        Task.Run(async () => 
        { 
            while(seconds > 0)
            {
                await Task.Delay(1000);
                seconds--;
                Action updateMethod = () => textBox1.Text = seconds.ToString();
                invoker.Invoke(updateMethod, new object[] { });
            }
        });
    }

var dispatcher=dispatcher.CurrentDispatcher;引发错误“名称“Dispatcher”在当前上下文中不存在”。Dispatcher仅为WPF。我当前正在Visual Studio中使用Windows窗体应用程序Studios@Blindy是的,你是对的-如果你没有引用WindowsBase程序集,那么就有Dispatcher/@TypeRMA1133您有权访问创建此线程的任何控件实例吗?实际上,您可以将一次控制分配给ISynchronizeInvoker,并将其传递给thread.var dispatcher=dispatcher.CurrentDispatcher;引发错误“名称“Dispatcher”在当前上下文中不存在”。Dispatcher仅为WPF。我当前正在Visual Studio中使用Windows窗体应用程序Studios@Blindy是的,你是对的-如果你没有引用WindowsBase程序集,那么就有Dispatcher/@TypeRMA1133您有权访问创建此线程的任何控件实例吗?实际上,您可以将once控件分配给ISynchronizeInvoker并将其传递给线程。