私がしているのは、realResult をチェックすることです。それが null の場合は、「作業中」を返し、BackGroundWorker を呼び出します。BackGround からのコールバックで、realResult を割り当て、NotifyPropertyChanged を呼び出します。async on プロパティはほとんど価値がありません。BackGroundWorker の構造と、キャンセルして進行状況を報告する機能が気に入っています。
private System.ComponentModel.BackgroundWorker backgroundWorker1;
private string textBackGround;
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public MainWindow()
{
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
InitializeComponent();
}
public string TextBackGround
{
get
{
if (!string.IsNullOrEmpty(textBackGround)) return textBackGround;
backgroundWorker1.RunWorkerAsync();
return "working";
}
}
// This event handler is where the actual,
// potentially time-consuming work is done.
private void backgroundWorker1_DoWork(object sender,
DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
e.Result = ComputeFibonacci(worker, e);
}
// This event handler deals with the results of the
// background operation.
private void backgroundWorker1_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
// Next, handle the case where the user canceled
// the operation.
// Note that due to a race condition in
// the DoWork event handler, the Cancelled
// flag may not have been set, even though
// CancelAsync was called.
textBackGround = "Cancelled";
NotifyPropertyChanged("TextBackGround");
}
else
{
// Finally, handle the case where the operation
// succeeded.
textBackGround = e.Result.ToString();
NotifyPropertyChanged("TextBackGround");
}
}
// This is the method that does the actual work. For this
// example, it computes a Fibonacci number and
// reports progress as it does its work.
string ComputeFibonacci(BackgroundWorker worker, DoWorkEventArgs e)
{
// Abort the operation if the user has canceled.
// Note that a call to CancelAsync may have set
// CancellationPending to true just after the
// last invocation of this method exits, so this
// code will not have the opportunity to set the
// DoWorkEventArgs.Cancel flag to true. This means
// that RunWorkerCompletedEventArgs.Cancelled will
// not be set to true in your RunWorkerCompleted
// event handler. This is a race condition.
if (worker.CancellationPending)
{
e.Cancel = true;
return "cancelled";
}
Thread.Sleep(1000);
if (worker.CancellationPending)
{
e.Cancel = true;
return "cancelled";
}
return "complete";
}
}