【问题标题】:Shouldn't Backgroundworker avoid main windows freeze?Backgroundworker 不应该避免主窗口冻结吗?
【发布时间】:2016-02-29 23:07:51
【问题描述】:

我正在尝试为 Office 加载项测试 Backgroundworker。简单的代码是这样的:

Imports Microsoft.Office.Tools.Ribbon
Imports System.ComponentModel
Imports System.Windows.Forms

Public Class Ribbon1
Dim f As New Form1
Dim bw As BackgroundWorker = New BackgroundWorker


Private Sub Ribbon1_Load(ByVal sender As System.Object, ByVal e As RibbonUIEventArgs) Handles MyBase.Load
    AddHandler bw.DoWork, AddressOf bw_DoWork
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) Handles Button1.Click
    System.Threading.SynchronizationContext.SetSynchronizationContext(New WindowsFormsSynchronizationContext())
    bw.RunWorkerAsync()
End Sub

Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    For x = 1 To 100
        f.Label1.Text = x.ToString
    Next
    f.Show()
End Sub
End Class

我将后台工作程序理解为可以与主应用程序一起运行的工具。但是主应用程序会冻结(或被禁用),直到后台工作人员完成其工作。这正常吗?

【问题讨论】:

  • 在DoWork中,不能引用这个需要访问UI线程的f.Label1.Text。如果要更新UI,必须在后台worker ProgressChanged事件中进行
  • 如果您使用read the documentation,您会看到:You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events.。这是使用线程的零规则 - 不要触摸 UI
  • 看起来问题已解决 - 不要在 DoWork 中调用 UI 元素 - 使用 BGW 事件

标签: vb.net visual-studio backgroundworker office-addins


【解决方案1】:

如果存在跨线程访问,则需要调用。 并且没有System.Threading.SynchronizationContext.SetSynchronizationContext(New WindowsFormsSynchronizationContext())的要求

做这样的事情。

Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    For x = 1 To 100
        Me.Invoke(Sub() f.Label1.Text = x.ToString)
    Next
    Me.Invoke(Sub() f.Show())
End Sub

【讨论】:

  • 谢谢大家的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 2018-05-03
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
相关资源
最近更新 更多