【问题标题】:WCF Service Begin method calls Background workerWCF Service Begin 方法调用后台工作者
【发布时间】:2014-04-21 12:33:43
【问题描述】:

我知道这方面的信息遍布整个互联网,但我找不到任何特定于我的场景的解决方案。

我正在使用 .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 方法之间插入我的操作。

【问题讨论】:

  • 通常,Begin and End 模式应该足够好。为什么需要后台工作者?最终,这一切都取决于被迁移的方法的作用。如果您可以分享更多关于需要做什么的信息,那么有人将能够帮助您。查看您问题中发布的示例,我认为没有必要拥有后台工作人员。
  • 感谢您的回复。我不想在 IIS 中托管它,所以每个请求都将由同一个线程处理,我不想阻塞调用线程
  • 不要创建单例服务。你检查过 WCF 实例上下文模式吗? msdn.microsoft.com/en-us/library/… 设置正确的上下文模式将确保您的服务不被阻塞
  • 我需要知道和理解的工作是为什么在大多数情况下如果方法被一个接一个地调用就会被拆分,除非在某些情况下我在互联网上发现调用了另一个服务。 codeproject.com/Articles/234085/…

标签: c# .net wcf asynchronous


【解决方案1】:

这篇 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,您也可以使用异步等待模式。

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

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

问我是否想了解具体如何执行上述操作的详细信息,我没有写这些,因为你会在网上找到很多相同的文章。

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 2011-03-17
相关资源
最近更新 更多