2013-11-01 27 views
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) 

工作正常。我可以做Task.Run_ _,調用DoWhatever,它都是開心和好。但是,如果我在另一個模塊中創建一個任務並調用DoWhatever,它不會觸發該委託,並且該可視組件不會更新。代碼是相同的,在相同的模塊中工作,在另一個模塊中它不工作。

我可能錯過了明顯的東西..任何人都在意指出我的錯誤?謝謝。

編輯 - 爲了澄清,其他模塊只是代碼,整個解決方案中只有一種形式。它在程序啓動時自動創建,沒有其他表單創建正在進行。

+0

嘗試'MyComponent.Invoke(Delegated,...)'順便說一句:你不是使用像'Form1'等東西,而是'f = new Form1',是嗎?因爲「默認實例」是線程特定的... – igrimpe

+0

試過了,沒有效果。它仍在調用「未委託」代碼,該代碼確實運行但可視組件未更新。我在各種模塊中使用代碼的唯一原因是爲了組織......我總是可以將它移回到一個模塊中,它可以工作......我只是很好奇它爲什麼沒有按預期工作。就表單本身而言,它是在啓動時創建的,即「主表單」,而不是手動創建的。 –

+0

我認爲委託人和委託人的目標方法必須公開才能發揮作用。 – PMF

回答

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線程之外,則將創建一個新的窗體實例。這意味着,內容會更新,但由於該表單未顯示,因此您不會看到它。

注意我做提醒您解決問題,通過使用OpenForms。我建議正確實例化表單!

添加一個新的模塊/類代碼:

Module Startup 

Public MyForm1 As Form1 

Public Sub main() 

    MyForm1 = New Form1 
    Application.Run(MyForm1) 

End Sub 

End Module 

轉到項目屬性 - >應用程序。禁用應用程序框架並選擇Sub Main作爲您的起始對象。在應用程序中,通過MyForm1訪問您的表單 - 或者任何您想要命名的表單。那麼問題就該消失。

+0

就是這樣。看到下面,很驚訝地看到一個「神祕形式」被創造出來。相應地調整代碼以使用該實例,現在它正在工作。謝謝 ;) –

相關問題