Silverlight Web服务回调性能 [英] Silverlight web service callback performance

查看:81
本文介绍了Silverlight Web服务回调性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个silverlight客户端与服务器上的Web服务进行通信。它有一个DoSomething方法,什么都不做,并返回void。



在客户端,我调用服务,并收听响应时间:

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

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

网络捕获表示响应在2ms内发回。然而,OnDoSomethingCompleted直到80ms后才被调用。

解决方案

通常,OnDoSomethingCompleted()会在UI线程上执行,即在幕后,有人正在调用一些代码(概念上)看起来像这样:

  Dispatcher.BeginInvoke )=> OnDoSomethingCompleted()); 

这意味着OnDoSomethingCompleted()将不会被执行,直到UI线程决定合作并运行它。大多数时间都很好,但有时候你希望它运行得更快。基本方法是使用线程池进行原始调用,这意味着响应将从同一线程池(不一定在同一个线程)处理。如果你可以在这个返回方法中做一些真正的处理,而不仅仅是自动把它重新放到UI线程上,这样可以加快你的处理速度。



Tomek (来自MS WCF小组)给出了一个很好的例子:



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

这也是我的理解,WCF连接的同步上下文设置,当你第一次打开它。这意味着WCF连接首次打开的任何线程都是处理所有后来调用的线程。所以在我自己的代码中,我做这样的事情:

  //在新的工作线程上旋转连接。 
//根据Tomek,这将导致所有的WCF调用从这个线程。
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
{
//告诉等待线程我们已经准备好了。
if(resetEvent!= null)
{
resetEvent.Set();
}
}
}


I have a silverlight client that communicates with a web service on a server. It has a DoSomething method that does nothing and returns void.

On the client, I call the service and listen to when the response comes back:

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

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

Network capture indicates the response is sent back within 2ms. However, OnDoSomethingCompleted is not called until 80ms later. Is there a way to change when the callback is executed?

解决方案

Normally, OnDoSomethingCompleted() would be executed on the UI thread, i.e., behind the scenes, something is calling some code that (conceptually) looks a little like this:

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

This means that OnDoSomethingCompleted() won't get executed until the UI thread decides to cooperate and run it. Most of the time that's fine, but there can be times when you want it to run faster. The basic approach is to use a thread pool to make the original call, which means that the response will get handled from the same thread pool (not necessarily ont he same thread). If you can do some real processing in this return method, and don't just automatically marshal it back onto the UI thread, this can speed up your processing somewhat.

Tomek (from the MS WCF team) gives a good example of how do this here:

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

It's also my understanding that the synchronization context for the WCF connection gets set when you first open it. This means that whatever thread the WCF connection is first opened on is the one that will handle all later calls. So in my own code, I do something like this:

// 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();

And then InitializeNotificationClient() looks something like this:

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();
         }
     }
 }

这篇关于Silverlight Web服务回调性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆