0

遇到任务和代表的奇怪问题。有问题的代码在 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,它不会触发委托并且该可视组件不会更新。代码是相同的,在同一个模块中有效,在另一个模块中无效。

我可能遗漏了一些明显的东西..有人愿意指出我的错误吗?谢谢。

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

4

1 回答 1

1

应该是线程特定的问题。检查这个:

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 线程之外,则会创建一个新的表单实例。这意味着,内容已更新,但由于未显示该表单,您将看不到它。

注意建议使用OpenForms. 我建议正确实例化表单!

在您的代码中添加一个新模块/类:

Module Startup

Public MyForm1 As Form1

Public Sub main()

    MyForm1 = New Form1
    Application.Run(MyForm1)

End Sub

End Module

转到项目属性-> 应用程序。禁用应用程序框架并选择Sub Main作为您的启动对象。在应用程序中,通过MyForm1- 或任何您想命名的方式访问您的表单。那么问题应该就没有了。

于 2013-11-01T13:54:08.310 回答