Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/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# 从单独的后台工作程序更改窗体_C#_Multithreading_Serial Port - Fatal编程技术网

C# 从单独的后台工作程序更改窗体

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设备获取数据。
一旦程序从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();}));