私はC#の初心者です。サードパーティのネットワークライブラリを使用して要求を送信する小さなプログラムを開発します。C#で同期呼び出しとして動作するように非同期呼び出しを変換する方法
キューにqTasks
という名前のリクエスト(単純な文字列)が格納されていて、そのリクエストを1つずつ順番に処理して実行中にキューを更新することができますエラーが返されました。
私はちょうどforループを使用して配列内のsend requestコマンドを1つずつ呼び出すことができますが、残念ながらsendrequest
コマンドはコールバックOnStageChanged
の非同期メソッドであり、次のリクエストを送信する前に結果を確認する必要があります。ステータスは「完了」です。
私は今、それを処理するために、以下の方法を使用しています:いつでもステージの変化コールバックメソッドOnStageChangeHandler
は、ライブラリによって呼び出されます、メイン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
}
}
を、それ完了すると「完了」状態になります。
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 - > B - > A - > B - >を....)。
私は、MSがウェブリクエストの処理を改善したので、シンクモードで動作できることを知りました。
それはそのようなループのような単純な流れで行うことができるように私は、私は同期呼び出し、上記のように非同期呼び出しを動作させるためのラッパーを持つことができるかどうかを知りたいのです:
while (qTaks.Count > 0)
{
if (!sendAndWaitReturn(qTasks.Dequeue())) {
// Report error and quit
}
}
// all tasks completed
このsendAndWaitReturn
メソッドは、要求を送信し、 "完了"のステータスを待ってから、結果を返します。
Iは、現在の要求のステータスを示すために制御フラグを使用することができるいくつかの例を発見し、コールバック関数が、この制御フラグを更新し、whileループを使用して、このフラグにUIスレッドがループ中:
while (!requestDone);
nextRequest
までrequestDone
まで続きません。しかし、この場合、UIはブロックされます。
UIスレッドをブロックせずに同期呼び出しとして動作するように非同期呼び出しを変換する方法はありますか?
SendRequestメソッドで処理されるwhatsの例を挙げることはできますか?これを行うには再帰が最善の方法です。しかし、論理に基づいて、その書き方を変えることができます。 – Thanigainathan
SendRequestメソッドは、ライブラリによって提供されます。実際、FiddlerCoreのSendRequestメソッドでは、必要なヘッダーとrequestBodyBytesがキュー内のデータから生成されます。 –
何か、もし 'SendRequest'が返ってきたら?それは 'タスク'を返しますか?しかし、これを同期させても、UIスレッドでこれを実行するとUIがフリーズすることを理解していますか? –