質問

新しいスレッドでジョブを開始するか、バックグラウンドワーカーを使用してジョブを開始しますが、前にそれを実行したことがなく、実行する方法を尋ねます。

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

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

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

ありがとう。

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

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

役に立ちましたか?

解決

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

これがお役に立てば幸いです。

他のヒント

ダウンロードするだけで、他の非同期処理は必要ありません。 WebClient クラス。既に独自のクラスを持っているので、それはおそらくあなたのための解決策ではありません。

それ以外の場合、 BackgroundWorker 。 MSDNページにその方法の例があります。

編集:短い話は:

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

本当にカスタマイズしたものが必要な場合は、いつでも独自の スレッド

個人的には BackgroundWorker を使い続けます。これには、ジョブのさまざまな段階の通知があります。 Thread を使用する場合、これらを自分で実装する必要があります。

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

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

バックグラウンドワーカーは動作するはずです... 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

スレッドに必要な場合、どのパラメーターに依存します。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top