私はWPFの初心者です。アプリケーションで一連の初期化手順を実行する必要があります。これらの手順は完了するまでに7〜8秒かかり、その間UIが応答しなくなります。これを解決するには、別のスレッドで初期化を実行します。
public void Initialization()
{
Thread initThread = new Thread(new ThreadStart(InitializationThread));
initThread.Start();
}
public void InitializationThread()
{
outputMessage("Initializing...");
//DO INITIALIZATION
outputMessage("Initialization Complete");
}
BackgroundWorker
についてのいくつかの記事と、長いタスクを実行するスレッドを作成せずにアプリケーションの応答性を維持する方法を読んだことがありますが、実装しようとして成功していません。 BackgroundWorker
を使用してこれを行いますか?
ありがとう、イーモン
using System.ComponentModel;
private readonly BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// run all background tasks here
}
private void worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
//update ui once worker complete his work
}
worker.RunWorkerAsync();
進行状況を追跡する(オプションですが、しばしば役立つ)
a)ProgressChanged
イベントをサブスクライブし、DoWork
でReportProgress(Int32)
を使用する
b)worker.WorkerReportsProgress = true;
を設定(@zagyにクレジット)
バックグラウンドワーカーの代わりにTask
の使用を検討することもできます。
これを行う最も簡単な方法は、例ではTask.Run(InitializationThread);
です。
バックグラウンドワーカーの代わりにタスクを使用することにはいくつかの利点があります。たとえば、.net 4.5の新しいasync/await機能は、スレッド化にTask
を使用します。 Task
に関するいくつかのドキュメントがあります http://msdn.Microsoft.com/en-us/library/system.threading.tasks.task(v = vs.110).aspx
using System;
using System.ComponentModel;
using System.Threading;
namespace BackGroundWorkerExample
{
class Program
{
private static BackgroundWorker backgroundWorker;
static void Main(string[] args)
{
backgroundWorker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
backgroundWorker.DoWork += backgroundWorker_DoWork;
//For the display of operation progress to UI.
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
//After the completation of operation.
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync("Press Enter in the next 5 seconds to Cancel operation:");
Console.ReadLine();
if (backgroundWorker.IsBusy)
{
backgroundWorker.CancelAsync();
Console.ReadLine();
}
}
static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 200; i++)
{
if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
backgroundWorker.ReportProgress(i);
Thread.Sleep(1000);
e.Result = 1000;
}
}
static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Completed" + e.ProgressPercentage + "%");
}
static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
Console.WriteLine("Operation Cancelled");
}
else if (e.Error != null)
{
Console.WriteLine("Error in Process :" + e.Error);
}
else
{
Console.WriteLine("Operation Completed :" + e.Result);
}
}
}
}
また、以下のリンクを参照して、Background
の概念を理解してください。
http://www.c-sharpcorner.com/UploadFile/1c8574/threads-in-wpf/
andrew Orsichが言ったことに加えて、あなたはそれについていくつかの例を読みたいかもしれません。
バックグラウンドワーカーとプログレスバーを使用したサンプルコード
http://devtoolshed.com/content/c-download-file-progress-bar
ここに小さなチュートリアルがあります
http://www.dotnetperls.com/backgroundworker
チュートリアルの最後に、progressbar + backgroundworkerの別の例へのリンクがあります。
私はこれを見つけました( WPFマルチスレッド:BackgroundWorkerを使用し、UIに進行状況を報告します。リンク )@Andrewの答えから欠落している詳細の残りを含む。
私が非常に便利だと思うことの1つは、ワーカースレッドがMainWindowのコントロール(独自のメソッド内)にアクセスできないことでしたが、メインウィンドウイベントハンドラー内でデリゲートを使用することは可能でした。
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
pd.Close();
// Get a result from the asynchronous worker
T t = (t)args.Result
this.ExampleControl.Text = t.BlaBla;
};
このリンクをお試しください MSDNのBackgroundWorkerクラス 使用方法の例が含まれています。