有关异步HTTP的问题,就是在BeginGetResponse的时候出错,来看看。

 

代码如下:

 

int c,cc=4096;

public static ManualResetEvent allDone = new ManualResetEvent(false);

FileStream fs = new FileStream( "file to post",.......);

asyncResult = request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), requestState);
allDone.WaitOne();
allDone.Reset();
c = fs.Read(b, 0, cc);
AsyncCallback callback = new AsyncCallback(WriteCallback);
int n = 0;
while (c > 0)
{
    asyncResult = requestState.dataStream.BeginWrite(b, 0, c, callback, requestState);
    requestState.waitHandle = ThreadPool.RegisterWaitForSingleObject(allDone, new WaitOrTimerCallback(TimeoutCallback), requestState, 3000, true);
    allDone.WaitOne();
    allDone.Reset();
    c = fs.Read(b, 0, cc);
}
requestState.dataStream.Close();

 

//特别留意这句Sleep的调用!!如果没有这一句,随后的EndGetResponse就会挂起

//一旦加上这句,就完全正常了,这是为何?

Thread.Sleep(100);


asyncResult = request.BeginGetResponse(new AsyncCallback(GetResponseCallback), requestState);
allDone.WaitOne();
allDone.Reset();

其中的一些callback函数我略掉了,这个程序经过测试,可以正常运行,文件能够正常上传到服务器上。

 

但是今天我特意测试在服务器出错的情况下程序会如何反应,于是我就特意指定了一个会导致HTTP服务器产生“内部服务器错误”(即500错误)的URL,结果程序在BeginGetResponse调用之后就失去反应,只能够杀掉进程。(特别说明:在HTTP服务器不产生错误的情况下,这段程序运行的很好,没有任何问题)

 

经过调试发现应该是在BeginGetResponse的回调函数中调用EndGetResponse的时候死掉了,不知道为何会这样。

 

后来我无意中在BeginGetResponse之前加入了一句Sleep的调用(上面代码中红色的那一行),没想到,只要加上了这么一句Sleep,EndGetResponse马上就恢复正常没有问题了!

 

这到底是为什么?实在让我不解?


//******************************************************************

我终于找到原因了!

 

原来就是因为我没有在BeginGetResponse的回调函数中使用异常处理!

 

原本回调函数是这样的:

 

        private static void GetResponseCallback(IAsyncResult asyncResult)
        {
                HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
                //运行到这里就死掉               

                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
                Stream s = response.GetResponseStream();
                StreamReader sr = new StreamReader(s, Encoding.Default);
                string ss = sr.ReadLine();
                sr.Close();
                s.Close();
                response.Close();
                MessageBox.Show(ss);

                allDone.Set();
        }

在加入了try...catch的语句之后居然就没有问题了。。。。我一直以为try...catch是可选的。。。。

 

原文地址:https://www.cnblogs.com/Fooo/p/1325355.html