我有一个与服务器上的Web服务通信的silverlight客户端。它有一个DoSomething方法,什么也不做,返回void。
在客户端上,我调用该服务并在响应响应时收听:
proxy.OnDoSomethingCompleted+=OnDoSomethingCompleted;
t0 = Environment.TickCount;
proxy.DoSomethingAsync();
void DoSomething(..)
{
t1 = Environment.TickCount;
}
网络捕获表示响应在2ms内发回。但是,OnDoSomethingCompleted直到80ms后才会被调用。有没有办法在回调执行时进行更改?
答案 0 :(得分:0)
通常,OnDoSomethingCompleted()将在UI线程上执行,即在幕后,有些东西正在调用一些代码(概念上)看起来像这样:
Dispatcher.BeginInvoke(() => OnDoSomethingCompleted());
这意味着在UI线程决定合作并运行它之前,不会执行OnDoSomethingCompleted()。大部分时间都很好,但有时你希望它运行得更快。基本方法是使用线程池进行原始调用,这意味着响应将从同一个线程池处理(不一定在同一个线程上)。如果你可以在这个返回方法中做一些真正的处理,并且不只是自动将它重新编组回UI线程,这可以加快你的处理速度。
Tomek(来自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();
}
}
}