2

これは非同期/スレッド化への私の最初のステップなので、事前にお詫びします。以下を実装するための最良の方法についてアドバイスが必要です...

プログレスバーを含む非静的なウィンドウフォームがあります。非同期httpダウンロードを管理するための静的メソッド「HttpSocket」もあります。したがって、静的メソッドからフォームの進行状況バーに直接アクセスすることはできません。

そこで、backgroundWorkerを使用してジョブを実行することを考えました。ただし、DoWorkは非同期メソッドも呼び出しているため、すべてのhttpリクエストが行われるとbackgroundWorkerレポートが完了しますが、http応答が受信され、データが解析された時期に基づいて進行状況バーを更新したいと思います。

私が思いついたこれを回避する1つのひどい方法は次のとおりです

private void buttonStartDownload_Click(object sender, EventArgs e)
{
  backgroundWorker1.RunWorkerAsync();
}

そして、backgroundWorker1_DoWorkにwhileループを配置して、リクエスト/レスポンスを比較します

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    //Trigger Asynchronous method from LoginForm
    DataExtract LoginForm = new DataExtract();
    LoginForm.DELogin();

    //Without While Loop backgroundWorker1 completes on http requests and not responses

    // Attempt to Monitor Progress of async responses using while loop
   // HttpSocket method logs RequestCount & ResponseCount

    while (HttpSocket.UriWebResponseCount < HttpSocket.UriWebRequestCount)
    {

        if (HttpSocket.UriWebResponseCount % updateInterval == 0) 
        {
            int myIntValue = unchecked((int)HttpSocket.UriWebResponseCount / HttpSocket.UriTotal);
            backgroundWorker1.ReportProgress(myIntValue);
        }

    }

}


private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // Change the value of the ProgressBar to the BackgroundWorker progress.
    progressBar1.Value = e.ProgressPercentage;

}

ただし、Whileループはパフォーマンスに影響を与え、進行状況を表示せずに通常は高速である非同期プロセスを遅くするため、これはこれを行うための最良の方法ではないことを認識しています。これを達成するための適切で最も効率的な方法、またはC#4.0を使用するBackgroundWorkerの有無にかかわらず、別の非同期スレッドからフォームプログレスバーを更新する別の方法を提案した後です。

ありがとうございました

O

4

1 に答える 1

1

要求/応答モデルのアーキテクチャを完全に理解していないと、バックグラウンドワーカーのwhileループが本質的に待機中のように見えます。

whileループの先頭にスリープ操作を挿入することで、進行状況を確認する頻度を大幅に減らすことができます。また、進行状況を報告する前に、チェックを削除して、応答カウントが整数値であるかどうかを確認することをお勧めします。

while (HttpSocket.UriWebResponseCount < HttpSocket.UriWebRequestCount) 
{ 
    Thread.Sleep(250); // sleep for 250 ms before the next check

    int myIntValue = (int)Math.Floor((double)HttpSocket.UriWebResponseCount / HttpSocket.UriTotal); 
    backgroundWorker1.ReportProgress(myIntValue); 
} 

静的プロパティHttpSocket.UriWebResponseCountとHttpSocket.UriWebRequestCountが更新され、スレッドセーフな方法で読み取られることを願っています。

于 2012-07-09T00:23:00.333 に答える