首先,我對C#和.NET框架有點新,但我試圖實現的是(恕我直言)相當簡單的目標,但我仍然遇到一些麻煩。HttpWebRequest.BeginGetRequestStream阻止UI線程
我的目標是使用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相當陌生,但我仍然沒有把握線程池和線程池的概念。
這正是第一個超越我的想法的解決方案。感謝您的確認。但是,出於好奇,有沒有辦法在函數的同一個線程中運行回調函數,將它們鏈接到事件(在這種情況下,worker_DoWork和GetRequestStreamCallback,可能在worker_DoWork中使用某種等待)? –
一種方法是使用AutoResetEvent。在DoWork中調用BeginGetRequestStream後調用event1.WaitOne(),然後在GetResponseCallback中調用event1.Set()。後臺工作線程將恢復。 – Japple
再次感謝,工作就像一個魅力。 –