C# 如何使用Control.Dispatcher.BeginInvoke修改GUI
我需要从一个需要很长时间才能完成的方法内部修改GUI。当我阅读其他帖子时, 解决方案之一是使用Control.Dispatcher.BeginInvoke在工作线程内设置GUI。 然而,我不知道如何在这里做到这一点C# 如何使用Control.Dispatcher.BeginInvoke修改GUI,c#,C#,我需要从一个需要很长时间才能完成的方法内部修改GUI。当我阅读其他帖子时, 解决方案之一是使用Control.Dispatcher.BeginInvoke在工作线程内设置GUI。 然而,我不知道如何在这里做到这一点 public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void button1_Click(object
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew( () =>
{
ProcessFilesThree();
});
}
private void ProcessFilesThree()
{
string[] files = Directory.GetFiles(@"C:\temp\In", "*.jpg", SearchOption.AllDirectories);
Parallel.ForEach(files, (currentFile) =>
{
string filename = Path.GetFileName(currentFile);
// the following assignment is illegal
this.Text = string.Format("Processing {0} on thread {1}", filename,
Thread.CurrentThread.ManagedThreadId);
});
this.Text = "All done!"; // <- this assignment is illegal
}
}
public分部类MainForm:Form
{
公共表格(
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
Task.Factory.StartNew(()=>
{
进程文件三();
});
}
私有void ProcessFilesThree()
{
字符串[]files=Directory.GetFiles(@“C:\temp\In”、“*.jpg”、SearchOption.AllDirectories);
Parallel.ForEach(文件,(当前文件)=>
{
字符串文件名=Path.GetFileName(当前文件);
//以下分配是非法的
this.Text=string.Format(“在线程{1}上处理{0}”),文件名,
Thread.CurrentThread.ManagedThreadId);
});
this.Text=“全部完成!”;//private void ProcessFilesThree()
{
//假设您有一个名为TestBox的textbox控件
//您希望在每次循环迭代时更新它
//带着一些信息
string someMessage=string.Empty;
对于(int i=0;i<10;i++)
{
Thread.Sleep(1000);//模拟一秒钟的工作。
someMessage=String.Format(“循环迭代{0}”,i);
testTextBox.Dispatcher.BeginInvoke(新操作((消息)=>
{
Text=message;
}),someMessage);
}
}
private void ProcessFilesThree()
{
//假设您有一个名为TestBox的textbox控件
//您希望在每次循环迭代时更新它
//带着一些信息
string someMessage=string.Empty;
对于(int i=0;i<10;i++)
{
Thread.Sleep(1000);//模拟一秒钟的工作。
someMessage=String.Format(“循环迭代{0}”,i);
testTextBox.Dispatcher.BeginInvoke(新操作((消息)=>
{
Text=message;
}),someMessage);
}
}
尝试以下操作:
msg = string.Format("Processing {0} on thread {1}", filename,
Thread.CurrentThread.ManagedThreadId);
this.BeginInvoke( (Action) delegate ()
{
this.Text = msg;
});
请尝试以下操作:
msg = string.Format("Processing {0} on thread {1}", filename,
Thread.CurrentThread.ManagedThreadId);
this.BeginInvoke( (Action) delegate ()
{
this.Text = msg;
});
我喜欢你的解决方案,但我不知道它为什么能工作。你能给我一个关于这个用法的详细描述吗?我知道,我们不应该从工作线程更新GUI。那么为什么我们可以从工作线程上异步调用的委托更新GUI呢?--thx@q0987-阅读Dispatcher.BeginInvoke上的文档,它将为您提供答案您正在查找。BeginInvoke方法创建windows消息并将消息发布到窗口。ProcessMessage在GUI线程上运行,拾取消息并调用委托。委托是lambda expression,因此可以访问msg局部变量。我喜欢您的解决方案,但不知道为什么它可以工作。您可以告诉我一些详细信息吗这个用法的所有描述?我知道,我们不应该从工作线程更新GUI。那么为什么我们可以从工作线程上异步调用的委托更新GUI呢?--thx@q0987-阅读Dispatcher.BeginInvoke上的文档,它将为您提供所需的答案。BeginInvoke方法将创建windows消息并发布在GUI线程上运行的window.ProcessMessage的消息会拾取消息并调用委托。委托是lambda表达式,因此可以访问msg局部变量。