私はbackgroundworkerでuserstateという概念を理解できないようです。 私が取り組んでいるアプリケーションで問題が発生しました。私が期待していなかったことが何か起こっている理由について説明が必要です。ProgressChangedコールバックでのBackgroundWorkerとUserStateの問題
私はもっと単純に問題を再現するデモアプリケーションを構築しています:
public class Tester
{
private BackgroundWorker _worker = new BackgroundWorker();
public void performTest()
{
Tester tester = new Tester();
tester.crunchSomeNumbers((obj, arg) =>
{
WorkerArgument userState = arg.UserState as WorkerArgument;
Console.WriteLine(string.Format("Progress: {0}; Calculation result: {1}", arg.ProgressPercentage, userState.CalculationResult));
});
}
public void crunchSomeNumbers(Action<object,ProgressChangedEventArgs> onProgressChanged)
{
_worker.DoWork += new DoWorkEventHandler(worker_DoWork);
_worker.ProgressChanged += new ProgressChangedEventHandler(onProgressChanged);
_worker.WorkerReportsProgress = true;
_worker.RunWorkerAsync(new WorkerArgument { CalculationResult=-1, BaseNumber = 10 });
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
WorkerArgument arg = e.Argument as WorkerArgument;
for (int i = 0; i < 10; i++)
{
// calculate total with basenumber
double result = arg.BaseNumber * (i * 10);
arg.CalculationResult = result;
worker.ReportProgress(i * 10, arg);
}
}
public class WorkerArgument
{
public int BaseNumber { get; set; }
public double CalculationResult { get; set; }
}
}
コンソールでこのコードを実行した場合のApp:
class Program
{
static void Main(string[] args)
{
Tester tester = new Tester();
tester.performTest();
Console.ReadLine();
}
}
これは結果である:
私が理解できないのは、計算結果がDoWorkメソッドのforloopで実行される各計算で異なる必要があることがはっきり分かりますが、同じことを繰り返す必要があります。
これはテストケースのエラーのように見えますが。コンソールアプリケーションでバックグラウンドワーカーを使用/テストしないでください。これはシングルスレッドで実行されます。 –
コンソールアプリケーションでバックグラウンドスレッドを実行すると何が問題になりますか。バックグラウンドスレッドを持つ他のUIと同じくらい便利です。 – btlog
@btlog:お読みください。スレッドには何も問題はありませんが、Bgwにはメッセージポンプが必要です。 –