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

时间:2014-04-21 12:33:44

标签: c# .net wcf asynchronous

我知道有关此信息的信息遍布互联网,但我找不到任何特定于我的方案的解决方案。

我正在使用.NET 4.5 VS 2012

我已经创建了一个WCF服务

#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

我不知道它是否可能或是否是一个好的设计。实际上,我在将旧代码迁移到新框架时遇到了这个问题,只是想在设计和代码方面做一些改进。

[编辑]
换句话说,我可以说我需要在beginX和endX方法之间插入我的动作。

1 个答案:

答案 0 :(得分:0)

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

上面的文章包含了应该有用的示例代码。

文章的要点是:

“*为了获得最佳性能,调用/实现上述异步模式时有两个原则:

·原则1:不要在Begin方法(上面的BeginDoWork)中进行重量级加权工作。 这样做的原因是您应该尽快返回调用线程,以便调用者可以安排其他工作。如果它是UI线程,则应用程序需要使用该线程来响应用户输入。如果可能的话,你应该总是将重要的操作放在不同的线程中。

·原理2:避免在Begin方法的同一个线程上调用End方法(上面是EndDoWork)。 End方法通常是阻塞的。它等待操作完成。如果实现End方法,您会看到它实际上调用了IAsyncResult.WaitHandle.WaitOne()。另一方面,作为常规实现(例如,此博客条目中附带的示例),此WaitHandle是分配了ManualResetEvent的延迟。只要你不打电话,它根本就不会分配。为了快速操作,这非常便宜。但是,一旦调用End,就必须分配它。调用End的正确位置来自操作的回调。调用回调时,意味着阻塞工作确实已完成。此时,您可以调用End来获取数据,而不会牺牲性能。*“

请注意,上面的帖子有点过时,因为您使用.Net 4.5,您也可以使用async await模式。

您还可以使用任务并行库(TPL)启动一个线程: Task.Factory.StartNew()...在WCF(.net 4.0+)中使用基于TPL的异步操作时,建议使用传统的异步(IasyncResult)。

如果您不能使用基于TPL的操作,您可以在使用相同API的委托上执行BeginInvoke。

问我是否想要详细说明如何进行上述操作,我没有写那些,因为你会在网上发现很多文章。