【问题标题】:What happens to a one way WCF service which opens some threads & leaves them to work on their own打开一些线程并让它们自行工作的单向 WCF 服务会发生什么
【发布时间】:2015-09-10 06:38:46
【问题描述】:

我有一个单向 WCF 服务,它调用一个打开 4 个线程并返回的方法。 让线程执行一些工作。

[OperationContract(IsOneWay=true)]
[WebInvoke(Method = "POST",
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           UriTemplate = "CalcinBackGround")]
public void CalcinBackGround(string somedata)
{
    CallAllWork(somedata);
    DoSomeOtherWork();
}

string CallAllWork(string somedata)
{
    Exception exc1 = null, exc2 = null, exc3 = null, exc4 = null;

    Thread thr1 = new Thread(() => SafeExecute(() => DoSomeWork1(new object[] {somedata}), out exc1));
    Thread thr2 = new Thread(() => SafeExecute(() => DoSomeWork2(new object[] {somedata}), out exc2));
    Thread thr3 = new Thread(() => SafeExecute(() => DoSomeWork3(new object[] {somedata}), out exc3));
    Thread thr4 = new Thread(() => SafeExecute(() => DoSomeWork4(new object[] {somedata}), out exc4));

    thr1.Start();
    thr2.Start();
    thr3.Start();
    thr4.Start();

    return "Done";
}

private static void SafeExecute(Action test, out Exception exception)
{
    exception = null;

    try
    {
        test();
    }
    catch (Exception ex)
    {
        exception = ex;
    }
}

从代码中可以看出, 我刚刚启动线程并从方法返回以执行一些其他操作。

这是让它们保持打开状态而不等待它们完成的好方法(因为它以单向服务工作。)还是有任何其他方法可以实现这一点?

为了清晰:我完全不关心线程中正在完成的工作,所以等待他们 完成对我来说毫无意义。

【问题讨论】:

  • 既然是单向服务,何不等他们完成呢?没有人会注意到。
  • 等待它完成意味着我无法进行其他不依赖于结果的任务。 (DoSomeOtherWork)
  • 当然可以。只需等待您完成所有其他工作之后的线程。
  • 您是否在 IIS 中托管?

标签: c# multithreading wcf


【解决方案1】:

这是让它们保持打开状态而不是等待它们完成的好方法吗 (因为它是以单向服务工作的。)还是有任何其他方式 要做到这一点?

首先,服务上的IsOneWay=true 仅表示服务不会返回响应(HTTP 200 代码除外)。它不保证服务调用将被成功处理。

因此,服务是否是单向的无关紧要,只有在那些线程的执行完成或失败对您不重要的情况下,让线程在您失去任何可见性的某些机器上的进程容器中运行才是可接受的。

如果是这种情况(失败并不重要),和/或您有一些其他机制来监控这些线程的进度并从任何失败中恢复,那么您的方法很好。

但是,我怀疑情况并非如此,您需要这些线程来完成处理并知道结果。如果是这种情况,那么取决于服务的托管方式非常重要。

如果您在 IIS 中托管,那么您不能依赖 appDomain 等待足够的时间来完成线程的运行。 IIS can and will 如果感觉可以从内存中卸载整个应用程序,这显然会杀死所有线程。

如果您托管在 Windows 服务中,这作为托管容器会稍微稳定一些,因为 Windows 服务往往保持可用,除非它们遭受某种未处理的异常或以其他方式崩溃。在这种情况下,您需要编写代码来处理此类事件。

在任何一种情况下,如果您使用单向调用,您将无法看到正在运行您的线程的进程。

我推荐的方法是使用backgrounder 来管理您的任务。

我使用过的一个叫做Hangfire,它允许您以持久的方式运行后台任务,并提供一个仪表板,以便您查看进度和处理故障。我当然会推荐这个,尽管它依赖于 SQL 服务器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多