在ASP中创建和终止线程有什么害处吗?. NET通过Response.End()

本文关键字:NET 通过 Response End 创建 ASP 终止 什么 线程 | 更新日期: 2023-09-27 18:01:18

我需要进行COM调用,并且只希望等待x秒的调用返回。如果调用在x秒内没有返回,我想结束请求。

创建Thread呼出

string output = null;
Thread t = new Thread(() => { output = SomeHelper.DoWork(); });
t.Start();
t.Join(timeout);
if (string.IsNullOrEmpty(output))                
     this.Send500();

结束响应的方法。

protected void Send500()
{
    Response.ClearHeaders();
    Response.ClearContent();
    Response.Status = "500 ServiceUnavailable";
    Response.StatusCode = 500;
    Response.Flush();
    Response.SuppressContent = true;
    Response.End();
}

Response.End()着火时,我得到Thread was being aborted错误。这是意料之中的。我对这个错误没有意见。对我想做的事情来说没问题。

当返回此错误时,是否有其他需要注意的原因?

在ASP中创建和终止线程有什么害处吗?. NET通过Response.End()

正常情况下,线程。中止是非常邪恶的,但是中止自己的线程是安全的。中止线程是危险的,因为中止可能发生在任何两个指令之间。但是终止自己的线程发生在一个定义良好的点上。这使得结果可以预测。

您没有中止正在执行可能超时的工作的线程。这很好,因为这将是一个非合作中止。您可能会有许多后台线程累积并耗尽一些资源的风险。但如果风险是可以承受的,你就没事了。如果不能容忍,将调用封装到类似Semaphore的同步区域的COM服务中,以绑定最大资源使用。

我想说你使用Response.Flush是有问题的,因为它很少需要刷新字节到客户端。这看起来像一个迷信的Flush

当返回这个错误时,是否有其他值得关注的原因需要注意吗?

你的主响应线程被ASP终止。. NET(参考Response.End实现)。你为COM对象启动的t线程保持活跃,只要SomeHelper.DoWork()返回或你的web应用程序的AppDomain被回收。这是否是个问题取决于DoWork()内部发生了什么,但从长远来看,它可能会损害您的服务器可伸缩性,至少。

即使你调用了t.Abort()(这从来都不是一个好主意),t线程也不会被中止,直到非托管调用返回。

我宁愿将SomeHelper.DoWork()移动到一个单独的进程,它可以很容易地杀死/重新启动,只要没有其他方法可以优雅地取消此调用。也许,实现这一点最简单的方法是通过为代理激活注册一个辅助DLL服务器来使COM对象脱离进程。您可能需要一个帮助器"工厂"COM对象来创建SomeHelper,并在需要时终止代理主机进程。