单向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;
}
}
从代码可以看出,我才刚刚开始整理。从方法返回以执行其他操作。
让它们开着是不是一个好方法&不等待它们完成(因为它在单向服务中工作)或者有其他方法使其发生吗?
为了清晰:我根本不关心线程中正在完成的工作,所以等待它们结束对我来说没有意义。
让它们开着是不是一个好方法&而不是等他们完成(因为它是在单向服务中工作)还是有其他方式让这一切发生?
首先,服务上的IsOneWay=true
仅仅意味着服务将不返回响应(除了HTTP 200代码)。它不提供任何服务调用将被成功处理的保证。
因此,服务是否是单向的是无关紧要的,只有当这些线程的执行完成或失败对您不重要时,才可以接受让线程运行在某些机器上的进程容器中,而您对这些机器失去了任何可见性。
如果是这种情况(失败并不重要),并且/或者您有一些其他机制来监视这些线程的进度并从任何失败中恢复,那么您的方法是好的。
然而,我怀疑情况并非如此,您需要这些线程来完成处理并知道结果。如果是这种情况,那么取决于服务的托管方式是非常重要的。
如果您的主机在IIS中,那么您不能依赖appDomain挂在足够的时间来完成线程的运行。如果愿意的话,IIS可以并且会从内存中卸载整个应用程序,这显然会杀死所有线程。
如果您在windows服务中托管,那么作为托管容器,这稍微稳定一些,因为windows服务倾向于保持可用,除非它们遭受某种未处理的异常或以其他方式崩溃。在这种情况下,您需要编写代码来处理此类事件。
在任何一种情况下,如果你使用单向调用,你将失去运行线程的进程的可见性。
我推荐的方法是使用后台来管理任务。
我用过一个叫Hangfire的工具,它允许你以持久的方式运行后台任务,并提供一个仪表板,这样你就可以看到进度和处理失败。我当然会推荐这个,尽管它依赖于SQL server。