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

时间:2014-05-02 19:55:33

标签: c# asp.net

我需要进行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错误。这是预料之中的。我错了。对于我尝试做的事情,这没关系。

当我需要注意这个错误时,还有其他原因需要注意吗?

2 个答案:

答案 0 :(得分:1)

通常,Thread.Abort非常邪恶,但是中止自己的线程是安全的。中止线程是危险的,因为中止可能发生在任何两个指令之间。但是,在一个明确定义的点上中止自己的线程。这使得后果可以预测。

您没有中止执行可能超时的工作的线程。这很好,因为这将是一次非合作中止。您冒着许多后台线程积累并耗尽一些资源的风险。但如果这种风险是可以忍受的,那你很好。如果不能容忍,请将调用包含在Semaphore类同步区域中的COM服务中,以限制最大资源使用量。

我说你使用Response.Flush是有问题的,因为很少需要将字节刷新到客户端。这对我来说似乎是一种迷信的Flush

答案 1 :(得分:1)

  

当我返回此错误时是否还有其他原因需要注意   需要注意吗?

您的主响应线程被ASP.NET中止(请参阅Response.End implementation)。只要t返回或您的网络应用的SomeHelper.DoWork()被回收,您为COM对象启动的AppDomain主题就会保持有效状态。这是否是一个问题取决于DoWork()内部的情况,但从长远来看,它可能会损害您的服务器可扩展性,至少。

即使您调用了t.Abort()(这绝不是一个好主意),在非托管调用返回之前,t线程也不会被中止。

我宁愿将SomeHelper.DoWork()移动到一个单独的进程,只要没有其他方法可以优雅地取消此调用,就可以轻松杀死/重新启动它。也许,实现这个的最简单方法是通过注册帮助器DLL Server for Surrogate Activation使您的COM对象处于进程外。您可能需要帮助“工厂”COM对象来创建SomeHelper并在需要时终止代理主机进程。

相关问题