C# 从单独的后台工作程序更改窗体
我有一个表单,加载后启动循环后台工作程序,每半秒从usb设备获取数据。C# 从单独的后台工作程序更改窗体,c#,multithreading,serial-port,C#,Multithreading,Serial Port,我有一个表单,加载后启动循环后台工作程序,每半秒从usb设备获取数据。 一旦程序从usb设备接收到一条新数据,它就会运行一项功能。 \u Dowork功能已启动 while (true) { portConnection.Write("?"); Thread.Sleep(50); } 然后,我有一个单独的例程,在收到数据时运行 private void portConnection_DataReceived(object sender, SerialDataReceivedEv
一旦程序从usb设备接收到一条新数据,它就会运行一项功能。
\u Dowork
功能已启动
while (true)
{
portConnection.Write("?");
Thread.Sleep(50);
}
然后,我有一个单独的例程,在收到数据时运行
private void portConnection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
}
这是无法在原始表单上设置值的例程,因为函数显然位于单独的线程上。如何使此例程能够影响原始表单?BackgroundWorker的“报告进度”部分就是为此制作的 这将使DoWork方法能够调用GUI线程上的方法 有关详细信息,请参阅本文 简言之,所需部件包括: 绑定已更改的进度处理程序:
bw.ProgressChanged += bw_ProgressChanged;
将BW设置为允许进度报告:
bw.WorkerReportsProgress = true;
实施进度变更方法:
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//your logic to be executed on the GUI thread here
}
然后从DoWork这样称呼它:
bw.ReportProgress( progressPercentage, userState )
private void InvokeIfRequired(Control target, Delegate methodToInvoke)
{
if (target.InvokeRequired)
target.Invoke(methodToInvoke);
else
methodToInvoke.DynamicInvoke();
}
progressPercentage
和userState
可以由用户将数据从后台线程传输到GUI线程上的ProgressChanged
方法。尝试以下操作:
bw.ReportProgress( progressPercentage, userState )
private void InvokeIfRequired(Control target, Delegate methodToInvoke)
{
if (target.InvokeRequired)
target.Invoke(methodToInvoke);
else
methodToInvoke.DynamicInvoke();
}
在您的ProcessStatsReceived
中调用该方法,并在methodToInvoke
中执行您的任务
您可以在ProcessStatusReceived中这样使用它:
InvokeIfRequired(this, new MethodInvoker(delegate() { this.lblStatus.Text = (string)e.Data; }));
查看
Invoke
和invokererequired
尝试类似于if(portConnection.invokererequired){portConnection.Write(“?”)}的方法。目标是我尝试使用的主窗体或单个对象?它就是窗体。我在应答器中添加了一个例子,效果非常好,因为数据在被转发到另一个函数之前进入了一个函数,我刚刚完成了上面的invokeFrequeired(这个,新的MethodInvoker(delegate(){this.sensorLocationUpdated();}));