4

新しいスレッドでジョブを開始するか、backgroundworker を使用してジョブを開始したいのですが、以前にそれを行ったことがなく、どのように行うべきかを尋ねました。

私のプログラムには、ファイルのリストを含むデータグリッドビューがあり、行ごとに 1 つのファイルがあります。ユーザーが行を選択してから「ダウンロードの開始」を押して、ダウンロードのバックグラウンドジョブを開始できるようにしたい。ダウンロードの進行状況のイベントを取得したい。

すべてを処理してイベントを発生させるクラス clsDownload がありますが、バックグラウンドワーキングを実装するにはどうすればよいですか?

クラス内で System.ComponentModel.BackgroundWorker を使用するか、これを処理するラッパーを作成するか、他のスレッド処理を使用する必要がありますか?

ありがとう。

編集:バックグラウンドワーカーでダウンロードを実装する方法がわかりません。小さな例はとてもいいでしょう。msdn の例では、うまくいきませんでした。

StartDownload 関数を持つダウンロード クラスがあります。クラスまたは呼び出し元でバックグラウンドワーカーを使用する必要がありますか? 「バカな感じ」

4

5 に答える 5

3

ダウンロードのみを行い、他の非同期処理は必要ありませんWebClient。クラスの非同期メソッドを使用するだけです。ただし、既に独自のクラスがあるため、それはおそらく解決策ではありません。

そうでなければ、あなたがBackgroundWorker言ったように使うことができます。MSDN ページには、その方法の例があります。

編集:短編小説は次のとおりです。

  • BackgroundWorker呼び出し元から を作成します。
  • バックグラウンド作業を開始したい場合はBackgroundWorker.RunWorkerAsync、 ;を呼び出します。
  • イベント ハンドラでDoWorkバックグラウンド作業を行います。この場合、ダウンロード クラスを開始します。
  • バックグラウンド作業を行っている間、時々チェックする必要がありCancelationPendingます;
  • 進捗状況を報告したい場合は、パーセンテージで計算して を呼び出す必要がありますReportProgress

また、本当にカスタマイズしたものが必要な場合は、いつでも独自の を作成できますThread

私は個人的に固執しBackgroundWorkerます。ジョブのさまざまな段階に関する優れた通知セットがあります。を使用する場合はThread、これらを自分で実装する必要があります。

また、コードが作成するインスタンスが多すぎないようにします。同時ダウンロードの数を制限し、その数を超えるものはすべてキューに入れたいと考えています。

于 2009-03-05T09:50:58.453 に答える
3

BackgroundWorkerUI でユーザーにフィードバックを提供する必要がある場合は、強くお勧めします。およびイベントは UI スレッドProgressChangedRunWorkerCompleted実行されるため、マーシャリングを行う必要がなく、コードがより複雑になる可能性があります。

于 2009-03-05T09:55:42.950 に答える
1

BackgroundWorker を組み込んだいくつかの異なるクラスを作成しました。私が一般的に行っているのは、ジョブが実行されているときに開くフォームに BackgroundWorker コンポーネントを配置し、そのインスタンスをジョブ クラスのコンストラクターに渡すことです。

ジョブクラスは次のようになります。

Private m_bwMain As BackgroundWorker

Public Sub New(ByVal bwMain As BackgroundWorker)
    m_bwMain = bwMain

    'additional setup code here
End Sub

ジョブを開始するには、[ダウンロードの開始] ボタンの Click イベント ハンドラーで次のようにします。

lblStatus.Text = "Initializing ..."
bgwMain.RunWorkerAsync(someFileName)

ジョブ クラスを現在のフォームのプライベート メンバーとして宣言し、BackgroundWorker.DoWork イベントでインスタンス化します。そこから、メソッドを呼び出してファイルをダウンロードできます。

Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork
    m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker))
    m_oJobEngine.DownloadFile(CStr(e.Argument))
End Sub

進行状況をユーザーに報告するために、クラスによって発生したイベントをメイン フォームで処理できます。ジョブ クラス オブジェクトの宣言に WithEvents キーワードが含まれていることを確認する必要があります。これらのハンドラーから、BackgroundWorker の ReportProgress メソッドを呼び出すことができます。ReportProgress 内から、進行状況を示すために UI に必要な変更を加えることができます。次に例を示します。

Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress
    bgw.ReportProgress(0, bytesTransferred)
End Sub
Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged
    lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred."
End Sub

お役に立てれば。

于 2009-03-05T17:43:09.410 に答える
0

clsDownload を使用するクラス (おそらく Form クラス) は、BackgroundWorker を使用してダウンロード メソッドを実行する必要があります。

于 2009-03-05T17:52:11.680 に答える
0

バックグラウンドワーカーは動作するはずです... MSDN に例があります。

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

または、次のようなこともできます。

WaitCallBack workCallBack= new WaitCallBack(DownloadMethod);
if(!ThreadPool.QueueUserWorkItem(workCallBack, "ThreadPooled")
{
   // Unable to Pool
}

// Work has been added to pool and will execute when possible

スレッドに必要なパラメータがあるかどうかによって異なります。

于 2009-03-05T09:50:08.500 に答える