【问题标题】:Changing a form from a separate background worker从单独的后台工作人员更改表单
【发布时间】:2012-08-07 08:52:09
【问题描述】:

我有一个表单,它在加载时会启动一个循环后台工作程序,它每半秒从 USB 设备获取数据。
一旦程序从 USB 设备接收到一条新数据,它就会运行一个函数。
_Dowork 函数有

while (true)
{
    portConnection.Write("?");
    Thread.Sleep(50);
}

然后我有一个单独的例程在收到数据时运行

private void portConnection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
}

这是无法在原始表单上设置值的例程,因为该函数显然位于单独的线程上。
我怎样才能使这个例程能够影响原始形式?

【问题讨论】:

  • InvokeInvokeRequired
  • 尝试类似 if (portConnection.InvokeRequired) { portConnection.Write("?"); }

标签: c# multithreading serial-port


【解决方案1】:

试试这样的:

private void InvokeIfRequired(Control target, Delegate methodToInvoke)
{
    if (target.InvokeRequired)
        target.Invoke(methodToInvoke);
    else
        methodToInvoke.DynamicInvoke();
}

在您的ProcessStatsReceivedmethodToInvoke 中调用方法做您的事情...

您可以在 ProccessStatusReceived 中这样使用它:

InvokeIfRequired(this, new MethodInvoker(delegate() { this.lblStatus.Text = (string)e.Data; }));

【讨论】:

  • 目标是主窗体还是我尝试使用的单个对象?
  • 就是表格。我在答案中添加了一个示例
  • 完美运行,由于数据在被转发到另一个函数之前进入一个函数,我刚刚完成了上述 InvokeIfRequired(this, new MethodInvoker(delegate() { this.sensorLocationUpdated();})) ;
【解决方案2】:

BackgroundWorker的报告进度部分就是为此而生的。

这将使 DoWork 方法能够调用 GUI 线程上的方法。

详情请参阅这篇msdn 文章。

简而言之,需要的部分是:

绑定进度更改处理程序:

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 )

progressPercentageuserState 可以是用户将数据从后台线程传输到GUI 线程上的ProgressChanged 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    相关资源
    最近更新 更多