【问题标题】:How to freeze the main thread from a worker thread如何从工作线程冻结主线程
【发布时间】:2014-09-10 02:50:53
【问题描述】:

我有一个后台线程,例如:

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才能在消息框被关闭之前进行操作?

【问题讨论】:

标签: .net vb.net multithreading


【解决方案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

【讨论】:

  • 您好,这是一个 WinForm 应用程序。我尝试了 InvokeRequired 或 Invoke something,但问题是 Main Class 不是控件,这意味着它无法调用 Invoke 方法
  • 您选择用来执行调用的控件或表单与方法无关。它只是用于获取线程并同步调用。你是说你没有主窗体?
  • 嘿 Mick,VB 中的 o => 是什么?是 Linq 吗?
  • => 是一个 lambda 语句。 stackoverflow.com/questions/3970219/c-sharp-lambda... 是的,它在 LINQ 中使用。我用C#,我没有检查vb中语法的有效性我认为是对的
  • 它有效。该行的 VB 版本是 _threadContext.Post(AddressOf ExitProgram, message)。非常感谢!
【解决方案2】:

您可以从您的类中调用调用方法。做这样的事情

创建接口

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

这样你就可以满足你的要求了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    相关资源
    最近更新 更多