我是C#中的新手,並且我將開發一個使用第三方網絡庫發送請求的小程序。如何隱藏異步調用在C#中同步調用工作
假設存儲在隊列qTasks
中的一些請求(只是簡單的字符串),它將按照提交的順序逐個處理這些請求,隊列可以在執行過程中更新,並且應該在任何時候停止有錯誤返回。
我可以只用一個for循環來逐個調用數組中的發送請求命令,但不幸的是sendrequest
命令是一個回調OnStageChanged
的異步方法,我需要在發送下一個請求之前檢查結果,當狀態是「完成」。
現在,我使用下面的方法來處理它:
在主UI線程,
// Put those request text in a queue names qTasks, then call a goNextTask() to process the request one by one.
// The queue can be updated by the UI thread at anytime, goNextTask will be called periodically to handle those pending request in the queue.
private void goNextTask(bool lastSuccess = true)
{
if (lastSuccess)
{
if (qTasks.Count > 0)
{
// continue to next request
string requestText = qTasks.Dequeue();
SendRequest(requestText, OnStageChangeHandler);
} else {
// Report for all request sent successfully
}
} else {
// stop and show error
}
}
回調方法OnStageChangeHandler
將由庫被稱爲每當階段的變化,它完成後將有狀態「完成」。
private void OnStageChangeHandler(object sender, StageChangeEventArgs e)
{
if (e.newState == SessionStates.Done)
{
// check result here
bool success = <...>
// then call the goNextTask in UI thread with the result of current request.
Application.Current.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
(Action)(() => goNextTask(success)));
}
}
雖然現在工作得很好,我認爲這是一個有點傻,因爲它有一個有點遞歸流(A - >乙 - > - >乙 - > ....)。
我瞭解到MS已經改進了Web請求處理,以便它可以在同步模式下工作。
我想知道如果我能有一個包裝上作上述異步調用的工作作爲一個同步調用,因此它可以在一個簡單的流程來完成的這樣一個循環:
while (qTaks.Count > 0)
{
if (!sendAndWaitReturn(qTasks.Dequeue())) {
// Report error and quit
}
}
// all tasks completed
這sendAndWaitReturn
方法將發送請求,然後等待狀態「完成」,然後返回結果。
我發現可以使用控制標誌指示當前請求的狀態的一些例子,回調函數會更新這個控制標誌,而使用while循環對這個標誌的UI線程循環:
while (!requestDone);
因此它不會繼續到nextRequest
直到requestDone
。但在這種情況下,UI將被阻止。
有沒有更好的方法來轉換異步調用作爲同步調用工作,而不會阻塞UI線程?
你可以舉一個例子說明SendRequest方法正在處理什麼?遞歸是做到這一點的最佳方式。但是,根據邏輯我們可以改變其書面的方式。 – Thanigainathan
該庫提供SendRequest方法。實際上,它是FiddlerCore的SendRequest方法,所需的頭文件和requestBodyBytes是從隊列中的數據生成的。 –
什麼,SendRequest返回?它會返回一個「任務」嗎?但即使你確實做到了同步,你也明白在UI線程上這樣做會凍結UI? –