HttpWebRequest.BeginGetRequestStream 阻塞 UI 线程
本文关键字:线程 UI 阻塞 BeginGetRequestStream HttpWebRequest | 更新日期: 2023-09-27 18:37:08
,我对C#和.NET Framework很陌生,但是我想要实现的是一个(恕我直言)简单的目标,但我仍然遇到一些麻烦。
我的目标是使用 WebRequest
类将数据发布到 Web 服务。我已经通读了文档和示例,尤其是这一部分:
方法需要一些同步安装任务 完成(DNS 解析、代理检测和 TCP 套接字 连接,例如),在此方法变为异步之前。作为一个 结果,绝不应在用户界面 (UI) 上调用此方法 线程,因为它可能需要一些时间,通常为几秒钟。
参考链接的示例,如何使方法GetRequestStreamCallback
并在后台线程中GetResponseCallback
运行?
这是我到目前为止得到的:
private void startTask()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerAsync();
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
updateStatus(e.ProgressPercentage);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
postData = /* data to be posted */;
byte[] postBytes = Encoding.UTF8.GetBytes(postData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://example.com");
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
}
private void GetRequestStreamCallback(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream stream = request.EndGetRequestStream(result))
{
stream.Write(Encoding.UTF8.GetBytes(postData), 0, Encoding.UTF8.GetBytes(postData).Length);
stream.Close();
}
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private void GetResponseCallback(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
Console.WriteLine(response.StatusDescription);
}
我使用BackgroundWorker
的原因是与UI交互,但我对替代解决方案持开放态度。我的问题是:当执行流到达worker_DoWork
函数结束时,工作线程会终止吗?甚至回调函数都是由worker自己执行的?如果没有,是否有其他方法可以使整个代码在单独的线程中运行?
对于(可能)愚蠢的问题,我深表歉意,但正如我所说,我对 .NET 很陌生,我仍然不掌握线程和线程池的概念。
DoWork 函数结束时完成,然后在启动 BackgroundWorker 的线程上引发 RunWorkerComplete。
在您的示例中,GetResponseCallback 将在调用请求的线程之后的不同线程上运行。BeginGetRequestStream 将在 DoWork 结束时返回到池中。
为简单起见,您可以使用同步版本或请求/响应方法(例如请求。GetRequestStream),因为你不再在UI线程上。UI 线程可以侦听 RunWorkedComplete,以从 UI 线程中获取调用结果。