2010-10-05 69 views
2

我有一個silverlight客戶端與服務器上的Web服務進行通信。它有一個DoSomething方法,它什麼都不做,並且返回void。Silverlight Web服務回調性能

在客戶端,我調用服務,並聽取當響應回來:

proxy.OnDoSomethingCompleted+=OnDoSomethingCompleted; 
t0 = Environment.TickCount; 
proxy.DoSomethingAsync(); 

void DoSomething(..) 
{ 
    t1 = Environment.TickCount; 
} 

網絡捕獲指示響應2ms的內發回。但是,OnDoSomethingCompleted直到80ms後纔會被調用。回調執行時有沒有辦法改變?

+1

是UI線程上執行的回調? – Gabe 2010-10-05 15:28:55

+0

顯示代碼OnDoSomethingCompleted。 – AnthonyWJones 2010-10-05 16:20:10

+0

DoSomethingAsync()在工作線程中調用。回調DoSomething()也在(不同的)工作線程中執行。 – Metro 2010-10-05 19:36:30

回答

0

通常情況下,OnDoSomethingCompleted()將UI線程,即在被執行時,幕後的東西是調用一些代碼(在概念上)看起來有點像這樣:

Dispatcher.BeginInvoke(() => OnDoSomethingCompleted()); 

這意味着OnDoSomethingCompleted( )在UI線程決定合作並運行之前不會執行。大多數時間沒問題,但有時候你希望它運行得更快。基本的方法是使用線程池進行原始調用,這意味着響應將從同一個線程池(不一定在同一個線程上)處理。如果你可以在這個返回方法中做一些真正的處理,並且不只是自動將它們編組回到UI線程,這可以加快你的處理速度。

託梅克(從MS WCF小組)給出瞭如何在這裏做一個很好的例子:

http://tomasz.janczuk.org/2009/08/improving-performance-of-concurrent-wcf.html

這也是我的理解,對於WCF連接的同步情況下被設定,當你第一次打開它。這意味着無論第一次打開WCF連接的線程是處理所有稍後調用的線程。因此,在我自己的代碼,我做這樣的事情:

// Spin up the connection on a new worker thread. 
// According to Tomek, this will cause all WCF calls to be made from this thread. 
ManualResetEvent resetEvent = new ManualResetEvent(false); 
wcfWorkerThread = new Thread(new ThreadStart(() => InitializeNotificationClient(resetEvent))); 
wcfWorkerThread.Name = "WcfWorkerThread"; 
wcfWorkerThread.Start(); 
resetEvent.WaitOne(); 

然後InitializeNotificationClient()看起來是這樣的:

private void InitializeNotificationClient(ManualResetEvent resetEvent = null) 
{ 
    try 
    { 
     notificationClient = GetRoomServiceClient(); 
     notificationClient.OpenAsync(callback); 
     notificationClient.InnerChannel.Faulted += new EventHandler(Channel_Faulted); 
     notificationClient.InnerChannel.Closed += new EventHandler(Channel_Closed); 
    } 
    finally 
    { 
     // Tell the waiting thread that we're ready. 
     if (resetEvent != null) 
     { 
      resetEvent.Set(); 
     } 
    } 
} 
+0

該回調已在工作線程上執行。此博客顯示使用併發Web服務調用時的性能改進。每次通話的持續時間仍然相同,因此如果必須按順序執行呼叫(例如,當第一個呼叫的結果輸入到第二個呼叫時),則不會有任何改進 – Metro 2010-10-05 20:39:28

+0

您是使用Net.TCP還是BasicHttpBinding作爲默認值?如果你關注性能,Net.TCP顯然是一個很好的選擇。但是,如果您有使用HTTP的其他原因,則可能需要查看使用WebRequest.RegisterPrefix()切換到Silverlight HTTP堆棧(而不是瀏覽器)。這應該是更快,但我沒有自己計時。 http://msdn.microsoft.com/en-us/library/dd920295(VS.95).aspx – 2010-10-05 22:40:20

+0

另外,還有一件事。您需要確保您從單獨的工作線程打開連接。根據Tomek的說法(從我們的談話中),從特定線程打開連接將導致所有稍後的WCF調用被封送到該線程。看到我的(編輯)答案的一些代碼。 – 2010-10-06 15:41:18