代表不在另一个模块工作

时间:2013-11-01 13:32:57

标签: vb.net multithreading delegates

遇到任务和委托的奇怪问题。有问题的代码在dotNET 4.5.1,VS2013下运行。在表单的代码中,我有一个更新网格的子,它检查是否需要调用,如果是,则调用委托。当一个任务运行在同一模块中调用时,它按预期工作,没有问题。无论是否有线程,网格都会正确更新。

但是,如果从另一个模块调用相同的东西,则委托永远不会被调用,并且可视组件不会更新。只是用一点点伪代码来澄清......

在表单的模块中:

Private Delegate Sub DoWhateverDelegate(ByVal _____)
Public Sub DoWhatever(ByVal _____)
    If MyComponent.InvokeReqired
        Dim Delegated As New DoWhateverDelegate(AddressOf DoWhatever)
        Debug.Print("The delegate fired")
        Invoke(Delegated, _____)
    Else
        ' .. carry on as usual ..
    End If
End Sub

...别处

Task.Run(Sub()
             ' .. various things I'd rather not block the UI thread with ..
             DoWhatever()
         End Sub)

工作正常。我可以执行调用DoWhatever的Task.Run_ _ ,这一切都很开心。但是,如果我在另一个模块中创建一个任务并调用DoWhatever,它不会触发委托,并且该可视组件不会更新。代码是相同的,在它工作的相同模块中,在另一个模块中它不相同。

我可能错过了一些明显的东西..有人想指出我的错误吗?感谢。

编辑 - 只是为了澄清,其他模块只是代码,整个解决方案中只有一个表单。它是在程序启动时自动创建的,没有其他表单创建。

1 个答案:

答案 0 :(得分:0)

应该是特定于线程的问题。检查一下:

Public Class Form1

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

    foo.DoSomething()

End Sub
End Class

具有委托的班级:

Public Class foo

Public Shared Sub DoSomething()
    Task.Run(Sub() UpdateText())
End Sub

Public Delegate Sub UpdateTextDelegate()
Public Shared Sub UpdateText()

    Dim f = Form1
    'Dim f As Form1 = Application.OpenForms("Form1")

    If f.InvokeRequired Then
        Dim d As UpdateTextDelegate = AddressOf UpdateText
        f.Invoke(d)
    Else
        f.TextBox1.Text = "Hi"
    End If

End Sub

End Class

运行代码,文本框不会更新。使用第二个f=....(从OpenForms获取引用的那个),它将被更新。 如果您只是尝试访问default instance并且您在UI线程之外,则将创建表单的新实例。这意味着,内容IS已更新,但由于该表单未显示,您将看不到它。

注意建议使用OpenForms来解决您的问题。我建议正确实例化表格!

在代码中添加新模块/类:

Module Startup

Public MyForm1 As Form1

Public Sub main()

    MyForm1 = New Form1
    Application.Run(MyForm1)

End Sub

End Module

转到项目属性 - >应用。禁用应用程序框架并选择Sub Main作为起始对象。在应用中,通过MyForm1访问您的表单 - 或者您想要命名的任何内容。那时问题就应该消失了。