单向WCF服务打开一些线程会发生什么?让他们自己工作

本文关键字:什么 他们 工作 自己 服务 WCF 线程 单向 | 更新日期: 2023-09-27 18:11:58

我有一个单向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;
    }
}

从代码可以看出,我才刚刚开始整理。从方法返回以执行其他操作。

让它们开着是不是一个好方法&不等待它们完成(因为它在单向服务中工作)或者有其他方法使其发生吗?

为了清晰:我根本不关心线程中正在完成的工作,所以等待它们结束对我来说没有意义。

单向WCF服务打开一些线程会发生什么?让他们自己工作

让它们开着是不是一个好方法&而不是等他们完成(因为它是在单向服务中工作)还是有其他方式让这一切发生?

首先,服务上的IsOneWay=true仅仅意味着服务将不返回响应(除了HTTP 200代码)。它不提供任何服务调用将被成功处理的保证。

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

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

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

如果您的主机在IIS中,那么您不能依赖appDomain挂在足够的时间来完成线程的运行。如果愿意的话,IIS可以并且会从内存中卸载整个应用程序,这显然会杀死所有线程。

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

在任何一种情况下,如果你使用单向调用,你将失去运行线程的进程的可见性。

我推荐的方法是使用后台来管理任务。

我用过一个叫Hangfire的工具,它允许你以持久的方式运行后台任务,并提供一个仪表板,这样你就可以看到进度和处理失败。我当然会推荐这个,尽管它依赖于SQL server。