首先,我对C#和.NET Framework一般都很陌生,但我想要实现的是(恕我直言)相当简单的目标,但我仍然遇到了一些麻烦。
我的目标是使用WebRequest
类将数据发布到Web服务。我已经阅读了documentation和示例,特别是这一部分:
BeginGetRequestStream方法需要一些同步设置任务 完成(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
函数的末尾时,工作者是否会终止?甚至回调函数都由工作人员自己执行?如果没有,是否有另一种方法可以使整个代码在一个单独的线程中运行?
我为(可能)愚蠢的问题道歉,但正如我所说,我是.NET的新手,我仍然没有掌握线程池和线程池的概念。
答案 0 :(得分:2)
BackgroundWorker线程在DoWork函数结束时完成,然后在启动BackgroundWorker的线程上引发RunWorkerCompleted。
在您的示例中,GetResponseCallback将在不同的线程上运行,因为调用request.BeginGetRequestStream的线程将在DoWork结束时返回到池。
为简单起见,您可以使用同步版本或请求/响应方法(例如request.GetRequestStream),因为您不再位于UI线程上。您的UI线程可以侦听RunWorkedCompleted以从UI线程中获取调用结果。