Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.Net从后台线程更新UI_Vb.net_Multithreading - Fatal编程技术网

VB.Net从后台线程更新UI

VB.Net从后台线程更新UI,vb.net,multithreading,Vb.net,Multithreading,我正在使用VB.Net开发一个类似调度程序的项目,应用程序从“Sub Main”开始,使用application.Run(),所有程序代码都是一个类中的处理程序,在这里创建并启动 Public Sub Main() m_App = New myApp m_App.Start() Application.Run() End Sub 在myApp内部,有一个计时器来控制任务的执行,它会为每个任务启动一个线程,当任务完成时,如果检测到错误,我们会尝试显示警报窗口。为了显示警报窗口(frm

我正在使用VB.Net开发一个类似调度程序的项目,应用程序从“Sub Main”开始,使用application.Run(),所有程序代码都是一个类中的处理程序,在这里创建并启动

Public Sub Main()
  m_App = New myApp
  m_App.Start()
  Application.Run()
End Sub
在myApp内部,有一个计时器来控制任务的执行,它会为每个任务启动一个线程,当任务完成时,如果检测到错误,我们会尝试显示警报窗口。为了显示警报窗口(frmAlert),我们测试了执行线程和主线程之间的两种不同通信方式:

1) 通过在任务对象中添加pulic事件,然后在主线程中将addhandler添加到函数中

2) 使用委托通知主线程

但是,警报窗口无法显示,并且没有错误报告。使用IDE进行调试后,发现警报窗口已成功显示,但任务线程完成后警报窗口将关闭

这是一个简化的任务类(使用两种通信方法进行测试)

以及主要的应用程序类

Imports System.Threading

Public Class myApp
    Private WithEvents _Timer As New Windows.Forms.Timer

    Private m_Process As New myProcess


    Public Sub Start()
        AddHandler m_Process.NotifyEvent, AddressOf Me.NotifyEvent
        m_Process.SetNotify(AddressOf NotifyDelegate)
        ProcessTasks()
    End Sub

    Private Sub Timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _Timer.Tick
        ProcessTasks()
    End Sub

    Public Sub ProcessTasks()
        _Timer.Enabled = False
        '
        Dim m_Thread = New Thread(AddressOf m_Process.Execute)
        m_Thread.Start()
        '
        _Timer.Interval = 30000
        _Timer.Enabled = True
    End Sub

    Public Sub NotifyEvent()
        frmAlert.Show()
    End Sub

    Public Sub NotifyDelegate()
        frmAlert.Show()
    End Sub

End Class
发现frmAlert是通过使用NotifyEvent或NotifyDelegate显示的,但在执行完成后会立即关闭

我可以知道我们如何从执行线程中弹出一个警报窗口,直到用户关闭它为止,该窗口可以一直保持在屏幕上吗


提前谢谢

如果希望主线程在子线程引发事件时执行任何操作,则需要确保主线程不会终止

Public Sub Start()
    AddHandler m_Process.NotifyEvent, AddressOf Me.NotifyEvent
    m_Process.SetNotify(AddressOf NotifyDelegate)
    ProcessTasks()

    Do While True  'You might want to add a boolean condition here to instruct the main program to terminate when you want it to.
        System.Threading.Thread.Sleep(200)
    Loop
End Sub

这将阻止主线程(程序)结束,从而可以处理子线程引发的任何事件。注意:您的类没有终止条件。

谢谢您的建议,但是t没有必要让myApp.start()保持运行,因为调度程序由计时器控制,如果没有计时器,应用程序将不会在此时结束。应用程序由application.run()启动,它将一直在内存中运行,直到我启动application.Exit()(这将在实际应用程序的NotifyIcon的ContextMenu中完成,上面的简化示例中未显示此部分)。警报窗口是通过从myProcess.Execute()调用frmAlert.show()显示的,但当myProcess.Execute()结束(即后台线程完成)时,它被关闭。即使我们让myApp.Start()继续运行,结果也是一样的。
Public Sub Start()
    AddHandler m_Process.NotifyEvent, AddressOf Me.NotifyEvent
    m_Process.SetNotify(AddressOf NotifyDelegate)
    ProcessTasks()

    Do While True  'You might want to add a boolean condition here to instruct the main program to terminate when you want it to.
        System.Threading.Thread.Sleep(200)
    Loop
End Sub