WCF服务Begin方法调用后台工作后台、方法、工作、WCF

2023-09-04 02:32:44 作者:眉眼如初

我知道这个信息为s $ P $垫遍布互联网,但我找不到具体到我的方案的任何解决方案。

I know information about this is spread all over internet, but I could not find any solution specific to my scenario.

我使用.NET 4.5 VS 2012

I am using .NET 4.5 VS 2012

我创建了一个WCF服务为

I have created a WCF service as

#region ISampleService Members

public IAsyncResult BeginServiceMethod(string msg, AsyncCallback callback, object asyncState)
{
    Thread.Sleep(10 * 1000);

    return new CompletedAsyncResult<String>(msg.ToUpper());
}

public string EndServiceMethod(IAsyncResult result)
{
    CompletedAsyncResult<String> res = result as CompletedAsyncResult<String>;
    return res.Data;
}

#endregion

现在我需要做的是调用从 BeginServiceMethod ,并最终启动一个后台工作,以执行其操作的另一种方法。在后台工作完成情况我想继续 EndServiceMethod 执行。

Now what I need to do is call another method from BeginServiceMethod, which eventually starts a background worker to perform its action. On background worker completed event I want continue the execution of EndServiceMethod.

我不知道它是否是可以或不可以或者它是否是一个良好的设计或没有。其实我碰到这个问题,同时迁移旧的code到新的框架,只是希望做一些设计改进,以及code。

I don't know whether it is possible or not or whether it is a good design or not. Actually I came across this problem while migrating old code to new framework and just want to do some improvement in design as well as code.

换句话说,我可以说我需要我的行动插上beginX和end​​X方法之间。

In other words I can say I need to plug in my actions in between beginX and endX methods.

推荐答案

这个MSDN博客文章要深入回答你的问题:http://blogs.msdn.com/b/wenlong/archive/2009/02/09/scale-wcf-application-better-with-asynchronous-programming.aspx

This msdn blog post should answer your question thoroughly: http://blogs.msdn.com/b/wenlong/archive/2009/02/09/scale-wcf-application-better-with-asynchronous-programming.aspx

以上文章包括示例code这应有助于。

The above article includes sample code which should help.

文章的要旨是:

*为获得最佳性能,以下是当你调用/执行上述异步模式的两个原则:

"*For best performance, here are two principles when you call/implement the above asynchronous pattern:

·原则1:不要做重磅作品里的Begin方法(这是BeginDoWork以上)。 这样做的原因是,你应该尽快返回调用线程,以便调用者可以安排其他工作。如果它是一个UI线程,应用程序需要使用线程来对用户输入的响应。你应该始终把沉重的操作在不同的线程如果可能的话。

· Principle 1: Do not do heavy-weighted work inside the Begin method (which is BeginDoWork above). The reason for this is that you should return the calling thread as soon as possible so that the caller can schedule other work. If it’s a UI thread, the application needs to use the thread to respond to user inputs. You should always put heavy operations in a different thread if possible.

·原则2:避免调用Begin方法的同一个线程结束的方法(这是EndDoWork以上)。 end方法通常阻止。它等待操作完成。如果要实现的最终方法​​,你会看到它实际上是调用IAsyncResult.WaitHandle.WaitOne()。另一方面,作为一个正常的实现(例如,附着在该博客条目的样本),这WaitHandle的是分配的ManualResetEvent延迟。只要你不把它称为,这将是未分配的。对于快速操作,这是pretty的便宜。然而,一旦最终被调用,你就必须分配它。正确的地方通话结束是从操作的回调。当调用回调,这意味着该阻挡工作真正完成。在这一点上,你可以调用最终获得在不牺牲性能检索的数据。*

· Principle 2: Avoid calling End method (which is EndDoWork above) on the same thread of the Begin method. The End method is normally blocking. It waits for the operation to complete. If you implement the End method, you would see that it actually calls IAsyncResult.WaitHandle.WaitOne(). On the other hand, as a normal implementation (for example, the sample attached in this Blog entry), this WaitHandle is a delay allocated ManualResetEvent. As long as you don’t call it, it would be not allocated at all. For fast operations, this is pretty cheap. However, once End is called, you would have to allocate it. The right place to call End is from the callback of the operation. When the callback is invoked, it means that the blocking work is really completed. At this point, you can call End to get data retrieved without sacrificing performance.*"

请注意,上面的职位是有点过时了,因为你使用的是.NET 4.5,你也可以使用异步等待模式。

Note that the above post is a bit dated, since you are using .Net 4.5 you can also use the async await pattern.

您也可以启动一个线程使用任务并行库(TPL): Task.Factory.StartNew()...当WCF(.NET 4.0 +),使用TPL基于异步操作,这是推荐在传统的异步(IAsyncResult的)。

You can also start a thread by using the Task parallel Library (TPL): Task.Factory.StartNew()... When using TPL based async operations in WCF (.net 4.0+) which is recommended over traditional Async (IasyncResult).

如果你不能使用TPL基础的业务,你可以在一个委托,它使用相同的API做的BeginInvoke。

In case you cannot use TPL based operations you can do a BeginInvoke on a delegate which uses the same API.

问我,如果你想在细节究竟是如​​何做到上面,我没有写这些,你会发现很多的文章在网络上是相同的。

Ask me if you want the details on exactly how to do the above, I didn't write those as you would find plenty of articles on the net on the same.