2013-07-23 38 views
0

我需要在單獨的線程上創建一個WCF ChannelFactory現在我面臨的問題是變量svc並不總是返回一個值:如何使用ThreadPool.QueueUserWorkItem同步返回(新的WaitCallback創建通道?

... 
    Dim svc As T = Nothing 
    Dim svcft As New DuplexChannelFactory(Of T)(caller, ep) 
    ThreadPool.QueueUserWorkItem(New WaitCallback(Sub(obj) svc = svcft.CreateChannel())) 
    ... 

大部分時間svc將返回一個空值,但有時它返回一個很好的借鑑。我在做什麼錯?

我根據爲波紋管YK1的評論修改我的代碼。它仍然沒有按沒有解決問題 - svc仍然並不總是如此:

Task.Factory.StartNew(
    Sub() 
     svc = svcft.CreateChannel() 
    End Sub 
).ContinueWith(
    Sub() 
     svcft = Nothing 
    End Sub 
) 
If svc Is Nothing Then 
    Throw New Exception("Creating service reference failed.") '<== get the error here... 
End If 

回答

1

您的問題是一種競爭條件。根據當前線程和線程池線程的安排方式,ThreadPool.QueueUserWorkItem之後的行可能有也可能沒有svc的正確值。這很糟糕,我們不想這樣做。

ThreadPool.QueueUserWorkItem是舊的方式在線程池線程上運行的東西在火災和遺忘的方式。你通常不想從那裏同步(儘管你可以使用events,但是,這些都是阻止方式)。

我們不想阻止應用程序線程了。所以,進來Async/AwaitTPL

這裏是你可以做的方式:

Async Function MyFuncAsync(Of T)() As Task 
    ... 
    Dim svc As T = Nothing 
    Dim svcft As New DuplexChannelFactory(Of T)(caller, ep) 
    svc = Await Task.Run(Funtion() svcft.CreateChannel()) 
    ... 
End Function 

如果你不是在.NET 4.5和不想使用async/await就可以直接使用TPL API。

... 
Dim svc As T = Nothing 
Dim svcft As New DuplexChannelFactory(Of T)(caller, ep) 
Task.Factory.StartNew(
    Sub() 
     svc = svcft.CreateChannel() 
    End Sub 
).ContinueWith(
    Sub(t) 
     `rest of code here 
    End Sub 
) 

如果你的主線程是UI線程(WPF /的WinForms),如果你想要同步回UI線程,那麼你可以繼續進行對UI線程上運行。 (async/await自動以上捕獲syncdhronizationcontext)。

... 
Dim svc As T = Nothing 
Dim svcft As New DuplexChannelFactory(Of T)(caller, ep) 
Task.Factory.StartNew(
    Sub() 
     svc = svcft.CreateChannel() 
    End Sub 
).ContinueWith(
    Sub(t) 
     `rest of code here 
    End Sub, 
TaskScheduler.FromCurrentSynchronizationContext()) 
+0

非常感謝YK1的輸入。你說得對,我在.Net 4.所以我嘗試了你推薦的TPL解決方案。我認爲仍然有一些我做錯了 - 變量svc仍然沒有被設置。下面是我的代碼的簡化版本:Task.Factory.StartNew(Sub()svc = svcft.CreateChannel())。ContinueWith(Sub()svcft = Nothing) – user2434400

+0

我已更新我的原始帖子以顯示我的最新代碼。它仍然不能解決問題。有什麼想法嗎? – user2434400

+0

我想通了 - 因爲我需要在主線程中使用svc,所以.ContinueWith函數不會有幫助。不久,我改變它.Wait()它的工作。非常感謝YK1! – user2434400

相關問題