vb.net / C# 外部处理程序

vb.net / C# External handler

我有一个用于显示进程选项的表单。 应用选项时:

frmOptions

For Each ltvi As ListViewItem In ltvProcesses.CheckedItems

     Dim proc As Process = CType(ltvi.Tag, Process)

     targeted_processes.Add(proc)
     AddHandler proc.Exited, AddressOf frmAET.a_target_process_has_been_exited
     proc.EnableRaisingEvents = True

Next

并且在 工具模块中 :

Public Sub a_target_process_has_been_exited(sender As Object, e As EventArgs)

        frmAET.btnStatus.ForeColor = Color.Red
        msgbox("OK")

End Sub

并且...消息框显示其消息,但颜色没有改变。 经过一些尝试,问题出在处理程序激活 a_target_process_has_been_exited 时。

如果我这样做(Button1 属于 frmAET,如 btnStatus):

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        a_target_process_has_been_exited()
End Sub

有效!但不是在我真正想要的时候(当一个过程结束时)。 所以,问题是当进程结束事件调用子程序时。

当我尝试指定它时(也许 frmAET 的子程序可以修改其控件):

AddHandler leproc.Exited, AddressOf frmAET.a_target_process_has_been_exited

错误:对非共享成员的引用需要对象引用

你能帮帮我吗?

您的 AddHandler 似乎使用了 AddressOf frmAET.a_target_process_has_been_exited,这意味着 frmAET 形式本身的方法.不是你所说的工具模块。

让我们考虑一下您的 frmOptions 是正确的并且 frmAET 包含它(删除了对 frmAET 的显式引用,因为它是本地的)

Public Sub a_target_process_has_been_exited(sender As Object, e As EventArgs)
    btnStatus.ForeColor = Color.Red
    MsgBox("OK")
End Sub

正如评论已经解释的那样,您的事件处理程序在另一个线程中被调用,您需要将自己同步到主 UI 线程。例如像这样:

Public Sub a_target_process_has_been_exited(sender As Object, e As EventArgs)
    Me.BeginInvoke(Sub() HandleProcessExit())
End Sub

Public Sub HandleProcessExit
    btnStatus.ForeColor = Color.Red
    MsgBox("OK")
End Sub

此版本将阻塞主 UI 线程,直到您单击 MsgBox 按钮。

您应该添加一些 Try/Catch 块。否则很难检测到另一个线程中的异常。

此代码依赖于 VB.NET 为您创建的隐式表单实例。我希望您的 frmAET 实际上是 My.Forms.frmAET 实例来完成这项工作。