C# 从另一个线程更改控件文本的正确方法
我有一个从5倒计时到0的线程: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
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并将其传递给线程。