ServerXmlHttpRequest 在执行 POST 时有时会挂起

ServerXmlHttpRequest hanging sometimes when doing a POST

我有一份工作,定期做一些涉及 ServerXmlHttpRquest 的工作来执行 HTTP POST。作业 运行s 每 60 秒。

通常 运行 没有问题。但是大约有五万分之一的机会(每两三个月)它会挂起:

IXMLHttpRequest http = new ServerXmlHttpRequest();

http.open("POST", deleteUrl, false, "", "");
http.send(stuffToDelete); <---hang

当它挂起时,即使是任务计划程序(如果它需要超过 3 分钟才能完成 运行,则启用了终止作业的选项)也无法结束该任务。我必须连接到远程客户的网络,进入服务器,然后使用任务管理器终止进程。

然后再过一三个月就好了。

最终我开始使用任务管理器创建进程转储,

所以我可以分析挂起的地方。在五次崩溃转储之后(在过去 11 个月左右)我得到了一个一致的画面:

ntdll.dll!_NtWaitForMultipleObjects@20()  
KERNELBASE.dll!_WaitForMultipleObjectsEx@20()
user32.dll!MsgWaitForMultipleObjectsEx()
user32.dll!_MsgWaitForMultipleObjects@20()
urlmon.dll!CTransaction::CompleteOperation(int fNested) Line 2496
urlmon.dll!CTransaction::StartEx(IUri * pIUri, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4453    C++
urlmon.dll!CTransaction::Start(const wchar_t * pwzURL, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4515    C++
msxml3.dll!URLMONRequest::send()
msxml3.dll!XMLHttp::send()
Contoso.exe!FrobImporter.TFrobImporter.DeleteFrobs Line 971
Contoso.exe!FrobImporter.TFrobImporter.ImportCore Line 1583
Contoso.exe!FrobImporter.TFrobImporter.RunImport Line 1070
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.HandleFrobImport Line 433
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.CoreExecute Line 71
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.Execute Line 84
Contoso.exe!Contoso.Contoso Line 167
kernel32.dll!@BaseThreadInitThunk@12()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8()

所以我做了一个 ServerXmlHttpRequest.send,但它从来没有 returns。它会在那里放置几天(导致系统错过金融交易,直到周日晚上我接到电话说它坏了)。

除非有人知道如何调试代码,否则它没有任何帮助,但转储时停滞线程中的寄存器是:

EAX 00000030
EBX 00000000
ECX 00000000
EDX 00000000
ESI 002CAC08
EDI 00000001
EIP 732A08A7
ESP 0018F684
EBP 0018F6C8
EFL 00000000 

ServerXmlHttpRequest 的默认超时

您可以使用serverXmlHttpRequest.setTimeouts(...)配置超时的四个类:

KB305053(决定保持连接打开的服务器将导致 serverXmlHttpRequest 等待连接关闭)似乎可能是问题所在。但是 30 秒的默认超时会解决这个问题。

可能的解决方法 - 将自己加入工作

Windows 任务计划程序无法终止任务;即使启用该选项也可以做。

我将考虑使用 Windows 作业 API 将我的 self 进程添加到作业中,并使用 SetInformationJobObject 设置我的流程有时间限制:

将我的进程限制为三分钟的执行时间:

PerProcessUserTimeLimit
If LimitFlags specifies JOB_OBJECT_LIMIT_PROCESS_TIME, this member is the per-process user-mode execution time limit, in 100-nanosecond ticks. Otherwise, this member is ignored.

The system periodically checks to determine whether each process associated with the job has accumulated more user-mode time than the set limit. If it has, the process is terminated.

If the job is nested, the effective limit is the most restrictive limit in the job chain.

虽然因为 Task Scheduler 使用 Job 对象来限制任务的时间,我也不希望 Job 对象也能限制任务。

编辑:作业对象不能按进程时间限制进程 - 仅限 用户 时间。并且当一个进程空闲等待一个对象时,它不会累积任何用户时间——当然不值得三分钟。

红利阅读

考虑切换到更新的、受支持的 API。

您错过的 msxml4.dll(和更新版本)中包含的 msxml3.dll library is no longer supported and is only kept around for compatibility reasons. Plus, there were a number of security and stability improvements