我们有一个由Delphi CGI同步调用的C#WebMethod(不要问!)。除我们切换到运行速度慢得多的灾难恢复环境外,此方法运行良好。问题是Delphi WinInet Web请求的超时时间为30秒,由于Microsoft确认的错误,无法更改该超时。在灾难恢复环境中,C#WebMethod可能要花费30秒以上的时间,而Delphi CGI却一无所获。

现在,我们已经对C#WebMethod进行了编码,以识别其所处的环境,如果它处于灾难恢复模式,那么我们将在线程中调用后续方法,并立即响应CGI,以使其在30秒之内完好无损。从理论上讲这是有道理的,但是我们发现这些线程调用是不稳定的,并且不会100%地执行。我们获得约70%的成功率。

这显然是 Not Acceptable ,我们必须将其提高到100%。我们已经在其他上下文中成功使用了Delegate.BeginInvoke()来调用线程,但是由于某些原因,它们不喜欢这样做。...显然没有EndInvoke(),因为我们需要立即响应CGI,这就是WebMethod的终结。

这是WebMethod的简化版本:

[WebMethod]
public string NewBusiness(string myParam)
{
    if (InDisasterMode())
    {
        // Thread the standard method call
        MethodDelegate myMethodDelegate = new MethodDelegate(ProcessNewBusiness);
        myMethodDelegate.BeginInvoke(myParam, null, null);
        // Return 'ok' to caller immediately
        return 'ok';
    }
    else
    {
        // Call standard method synchronously to get result
        return ProcessNewBusiness(myParam);
    }
}

如果在WebService WebMethod环境中使用,这种“即发即弃”调用是否会因某些原因而失败?如果是这样,那么还有其他选择吗?

不幸的是,改变Delphi面不是我们的选择-解决方案必须在C#面。

您能提供的任何帮助将不胜感激。

最佳答案

您是否尝试在您的方法中使用“HttpContext”?如果是这样,则应首先将其存储在本地变量中...而且,我只需使用ThreadPool.QueueUserWorkItem 即可。

例子:

[WebMethod]
public string NewBusiness(string myParam)
{
    if (InDisasterMode())
    {
        // Only if you actually need this...
        HttpContext context = HttpContext.Current;

        // Thread the standard method call
        ThreadPool.QueueUserWorkItem(delegate
        {
            HttpContext.Current = context;

            ProcessNewBusiness(myParam);
        });

        return 'ok';
    }
    else
    {
        // Call standard method synchronously to get result
        return ProcessNewBusiness(myParam);
    }
}

10-08 19:36