遇到任务和委托的奇怪问题。有问题的代码在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,它不会触发委托,并且该可视组件不会更新。代码是相同的,在它工作的相同模块中,在另一个模块中它不相同。
我可能错过了一些明显的东西..有人想指出我的错误吗?感谢。
编辑 - 只是为了澄清,其他模块只是代码,整个解决方案中只有一个表单。它是在程序启动时自动创建的,没有其他表单创建。
答案 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
访问您的表单 - 或者您想要命名的任何内容。那时问题就应该消失了。