新しいスレッドとして実行中のクラス
-
03-07-2019 - |
質問
新しいスレッドでジョブを開始するか、バックグラウンドワーカーを使用してジョブを開始しますが、前にそれを実行したことがなく、実行する方法を尋ねます。
私のプログラムには、ファイルのリストを含むデータグリッドビューがあり、行ごとに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を使用してダウンロードメソッドを実行する必要があります。