【问题标题】:New Thread is still blocking UI-Thread新线程仍在阻塞 UI-Thread
【发布时间】:2010-11-11 16:26:20
【问题描述】:

当单击按钮时,我会启动一个单独的thead,它填充一个网格并使用 webbrowser-control 执行某些操作。但是当按钮被点击时,新线程似乎不是独立的,导致 UI 冻结,直到新线程完成。

代码如下:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
    FindCustomerLocation()
    e.Handled = True
End Sub


Private Sub FindCustomerLocation()
    Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
    Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
    Findcontractor_Thread.Start()
End Sub


Delegate Sub FindContractorDelegate(ByVal igGrid As Infragistics.Windows.DataPresenter.XamDataGrid, ByVal webbrowser As Controls.WebBrowser)


Private Sub FindContractor_ThreadExecute()
    Dim threadControls(1) As Object
    threadControls(0) = Me.XamDataGrid1
    threadControls(1) = Me.WebBrowserMap

    Dim m As FindContractorDelegate = AddressOf FindContractor_WorkingThread
    Me.Dispatcher.BeginInvoke(m, threadControls)
End Sub


Private Sub FindContractor_WorkingThread()

    Mouse.OverrideCursor = Cursors.Wait

'Do something...

    Mouse.OverrideCursor = Nothing
End Sub

我做错了什么?

谢谢, 尼尔斯

【问题讨论】:

    标签: vb.net multithreading


    【解决方案1】:

    您可能在“做某事”中使用 winforms 控件。控件只能在 UI 线程中进行 mainupulated。

    因此,“BeginInvoke”在这个 UI 线程中调用目标。所以你创建了并行线程,但整个想法又在 UI 线程中做。

    【讨论】:

    • 在我的单独线程中,我使用了 winforms,系统确实抛出了一个异常报告你在说什么。
    【解决方案2】:

    您的新线程具有更高的优先级,因此会导致 UI 冻结它所做的一切(只要它是部分密集的)

    【讨论】:

      【解决方案3】:

      使用Dispatcher.CurrentDispatcher.BeginInvoke 来解决这个问题。

      出现此问题的原因是 Dispatcher 实例在 GUI 线程上调用,但 Dispatcher.CurrentDispatcher 将为当前正在执行的线程创建一个新的 Dispatcher 实例(如果不存在)。

      这在概念上类似于 Windows 如何为创建的新线程创建消息队列,这些线程本身创建一个 winform。

      【讨论】:

        【解决方案4】:
        Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
        Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
        Findcontractor_Thread.Start()
        

        用于带参数的线程调用

        trd_copy.ParameterizedStart(src)
        
        Delegate Sub nameofDelegate(s As Integer)
        Sub nameofDelegate+NameofSub(ByVal s As Integer)
        If Form1.ProgressBar1.InvokeRequired Then
            Dim d As New nameofDelegate (AddressOf nameofDelegate+NameofSub)
            NameOfYourForm.Invoke(d, New Object() {s})
        Else
            If s = 1 Then
                NameOfYourForm.ProgressBar1.Refresh() ** Or other Gui Functions
            Else
        
            End If
        End If
        

        结束子

        对于没有参数的线程调用

        trd_copy.Start()
        
        Delegate Sub nameofDelegate()
        Sub nameofDelegate+NameofSub()
        If Form1.ProgressBar1.InvokeRequired Then
            Dim d As New nameofDelegate (AddressOf nameofDelegate+NameofSub)
            NameOfYourForm.Invoke(d, New Object())
        Else
           NameOfYourForm.ProgressBar1.Refresh() ** Or other Gui Functions
        End If
        End Sub
        

        记住,当你第一次启动一个线程并且你在一个模型中编码时,你必须将(我)传递给初始线程,因为 VB 有一个“默认表单实例”的概念。对于应用程序命名空间中的每个表单,都会在 Forms 属性下的 My 命名空间中创建一个默认实例。

        这只是像这样添加一个额外的参数

        Private Sub FindCustomerLocation()
        Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
        Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
        Findcontractor_Thread.Start(me)
        End Sub
        
        
        
        Private Sub FindContractor_ThreadExecute(beginform as *NameOfFormComingFrom*)
        Dim threadControls(1) As Object
        threadControls(0) = Me.XamDataGrid1
        threadControls(1) = Me.WebBrowserMap
        
        
        FindContractor_WorkingThread(threadControls,beginform)
        End Sub
        
        
        Delegate Sub FindContractor_WorkingThread(s As Integer,beginform as   *NameOfFormComingFrom*)
        Sub FindContractor_WorkingThreadInvoke(ByVal s As Integer,beginform as *NameOfFormComingFrom*)
        If beginform.mouse.InvokeRequired Then
            Dim d As New FindContractor_WorkingThread(AddressOf    FindContractor_WorkingThreadInvoke)
            beginform.Invoke(d, New Object() {s,beginform})
        Else
             beginform.Mouse.OverrideCursor = Cursors.Wait
        
            'Do something...
        
            beginform.Mouse.OverrideCursor = Nothing
        End If
        End Sub
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多