如何从工作线程冻结主线程

时间:2014-09-10 02:50:53

标签: .net vb.net multithreading

我有一个后台主题:

Public Class Main
   Private Sub StartBackgroundThread()
       Dim threadStart As New Threading.ThreadStart(AddressOf DoStuffThread)
       Dim thread As New Threading.Thread(threadStart)
       thread.IsBackground = True
       thread.Name = "Background DoStuff Thread"
       thread.Start()
   End Sub

   Private Sub DoStuffThread()
       Do
           Do things here .....
           If something happens Then
               ExitProgram(message)
           End If
       Loop
   End Sub

   Private Sub ExitProgram(ByVal message As String = "")
       MessageBox.Show(message)
       Application.Exit()
   End Sub

End Class

线程一直运行以检查某些条件,一旦满足条件,我想调用ExitProgram退出整个应用程序。问题是弹出消息框而不冻结主线程(UI),导致用户仍然可以在不允许的UI上操作。

我想知道如何调用ExitProgram方法,因为它是从主线程调用的,所以在消息框被解除之前无法操作UI?

2 个答案:

答案 0 :(得分:1)

取决于您的应用程序的类型......

C# Windows Forms Application - Updating GUI from another thread AND class?

或者这......

Thread invoke the main window?

或者这......

Using SynchronizationContext for sending events back to the UI for WinForms or WPF

将回答你的问题,即......

Public Class Main
   Dim _threadContext As SynchronizationContext

   Private Sub StartBackgroundThread()
       ' set on the UI Thread
       _threadContext = SynchronizationContext.Current;
       Dim threadStart As New Threading.ThreadStart(AddressOf DoStuffThread)
       Dim thread As New Threading.Thread(threadStart)
       thread.IsBackground = True
       thread.Name = "Background DoStuff Thread"
       thread.Start()
   End Sub

   Private Sub DoStuffThread()
       Do
           Do things here .....
           If something happens Then
               _message = message
               _threadContext.Post(o => { ExitProgram(message) }, null)
           End If
       Loop
   End Sub

   Private Sub ExitProgram(ByVal message As String = "")
       MessageBox.Show(message)
       Application.Exit()
   End Sub

End Class

答案 1 :(得分:1)

您可以从班级调用invoke方法。做这样的事情

创建界面

Public Interface IContainerForm
    Function Invoke(ByVal method As System.Delegate) As Object
End Interface

在您的调用表单上实现此接口,并将其引用传递给类

在Form类上执行此操作

Public Class MyClass
    Implements IContainerForm

Private _obj As New MainClass(Me)

   Public Function Invoke1(ByVal method As System.Delegate) As Object Implements IContainerForm.Invoke
        Return Me.Invoke(method)
    End Function
End Class

在您的主要课程中执行此操作

 Dim _ContainerForm As IContainerForm

 Sub New(ByVal ContainerForm As IContainerForm)
        Me._ContainerForm = ContainerForm
    End Sub

立即调用

_ContainerForm.Invoke

通过这种方式,您可以满足您的要求。