Visual C++ XMLHTTP 和 ServerXMLHTTP异步调用

转载于微软learn, 调用有时候真的会阻塞,所以使用异步方式,可以在message pump中设置timeout:

Starting with MSXML version 3.0, the XMLHTTP request object uses Urlmon.dll. If you set the async parameter to VARIANT_TRUE when you call the open method, URLMON uses the message queue mechanism to notify the application when data becomes available, and the readyState property of the XMLHTTP request object is changed, as in the following example:

C++Copy

hr=pXMLHTTPReq->open("POST", "http://www.server1.com/test.asp", VARIANT_TRUE);

In a Visual C++ application, you must use a message pump to receive and dispatch messages. If the application does not handle the incoming messages properly, the application may stop responding (hang) because the readystate property of the XMLHTTP request object is not changed.

 Note

This issue is specific to Visual C++ developers.

 Note

This information is specific to Windows XP. By default, Windows XP ships with MSXML3.0 Service Pack 2 (SP2).

More information

With the MSXML 2.5 parser that ships with Microsoft Windows 2000, no such message pump is needed. With Windows XP, MSXML 3.0 SP2 is installed in Replace mode, so you may encounter this problem.

The following is a sample implementation of the message pump with the XMLHTTP request object. To test it, paste the code into a .cpp file, then compile and run the file as a Win32 Console application project.

C++Copy

#import "msxml3.dll"
using namespace MSXML2; // For Msxml3.dll.

#include "stdio.h"

void dump_com_error(_com_error &e)
{
    printf("Error\n");
    printf("\a\tCode = %08lx\n", e.Error());
    printf("\a\tCode meaning = %s", e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
}

int main()
{
    HRESULT hr = CoInitialize(NULL);

    try{
        IXMLHTTPRequestPtr pXMLHTTPReq = NULL;
        hr=pXMLHTTPReq.CreateInstance(__uuidof(XMLHTTP30));

        //Uncomment the following lines if you are using ServerXMLHTTPRequest.
        //IServerXMLHTTPRequestPtr pXMLHTTPReq = NULL;
        //hr=pXMLHTTPReq.CreateInstance(__uuidof(ServerXMLHTTP30));

        hr=pXMLHTTPReq->open("POST", "http://www.server1.com/test1.asp", VARIANT_TRUE);

        hr = pXMLHTTPReq->setRequestHeader("charset", "UTF-8");
        hr=pXMLHTTPReq->send("<?xml version=\"1.0\" encoding=\"UTF-8\"?><REQUEST>request1</REQUEST>");

        long readyState = READYSTATE_UNINITIALIZED;
        MSG msg;
        while (readyState != READYSTATE_COMPLETE)
        {
            //Without this message pump, readyState does not change.
            if (PeekMessage(&msg, 0, 0 ,0, PM_REMOVE))
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }

            readyState = pXMLHTTPReq->GetreadyState();

        }
        MessageBox(NULL, "readyState is COMPLETE ", "readystate", MB_OK);

        long status= pXMLHTTPReq->Getstatus();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
    }
    return 0;
}

 Note

Asynchronous processing in practice is more complicated. You should test your application in synchronous mode before you try to use asynchronous mode.

When you use the SeverXMLHTTPRequest object, you must run the Proxycfg utility to set the proxy information. For more information, see Frequently asked questions about ServerXMLHTTP.

ServerXMLHTTP does not use Urlmon.dll. However, when you use ServerXMLHTTP in asynchronous mode, you also need this message pump because the parser fires the event by posting messages back to the thread.

ServerXMLHTTP also includes a method called waitForResponse that is not available with XMLHTTP. The waitForResponse waits while an asynchronous request is processed. The waitForResponse method pumps window messages automatically, so the client's application code does not need to do this. This allows the application code to be simplified, as follows:

C++Copy

hr=pXMLHTTPReq.CreateInstance(__uuidof(ServerXMLHTTP30));

hr=pXMLHTTPReq->open("POST", "http://www.server1.com/test1.asp", VARIANT_TRUE);

hr = pXMLHTTPReq->setRequestHeader("charset", "UTF-8");
hr=pXMLHTTPReq->send("<?xml version=\"1.0\" encoding=\"UTF-8\"?><REQUEST>request1</REQUEST>");

VARIANT Timeout;
VariantInit(&Timeout);
Timeout.vt = VT_I4;
Timeout.lVal = 60; // Timeout value of 60 seconds.

VARIANT_BOOL bSucceeded;
//Passing vtMissing as the first parameter sets the timeout value to infinite.
hr = pXMLHTTPReq->waitForResponse(Timeout, &bSucceeded);

long status= pXMLHTTPReq->Getstatus();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值