私は一日中コードサンプルを探して試してみて、最終的に機能するもの (つまり、UI をブロックしない Caliburn コルーチンを使用した非同期操作) を見つけたので、それを共有できるようにします。
私が理解している限り、Caliburn のコルーチンはスレッドを処理しません。それらは、非同期実行と制御コードを 1 つのメソッドで処理するエレガントな方法を提供するだけです。バックグラウンド スレッドで操作を処理するには、BackgroundWorkers などの他のツールを使用する必要があります。
Silverlight の場合、このリンクは非常に興味深いものでした。目的は、コルーチン呼び出しをラップするクラスにバックグラウンド ワーカーを含めることでした。
私はわずかな違いで WPF でそれを望んでいたので、私のマシンで動作する次のコード サンプルになりました。
ラッピングクラス:
using System;
using Caliburn.Micro;
using System.ComponentModel;
namespace MyApp.Implementation
{
public class BackgroundCoRoutine : IResult
{
private readonly System.Action action;
public BackgroundCoRoutine(System.Action action)
{
this.action = action;
}
public void Execute(ActionExecutionContext context)
{
using (var backgroundWorker = new BackgroundWorker())
{
backgroundWorker.DoWork += (e, sender) => action();
backgroundWorker.RunWorkerCompleted += (e, sender) => Completed(this, new ResultCompletionEventArgs());
backgroundWorker.RunWorkerAsync();
}
}
public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
}
}
そして、私の ViewModels の 1 つでは、次のようになります。
public IEnumerable<IResult> ProcessTask()
{
IsBusy = true;
TempObject result = null;
for (int i = 1; i < 4; i++) // Simulates a loop that processes multiple items, files, fields...
{
yield return new BackgroundCoRoutine(() =>
{
System.Threading.Thread.Sleep(1000); // Time consuming task in another thread
result = new TempObject("Item " + i);
});
MyObservableCollection.Add(result); // Update the UI with the result, in the GUI thread
}
IsBusy = false;
}
これにより、ProcessTask ボタンをクリックしても UI がフリーズせず、計算結果がバックグラウンド ワーカー プロセスによって利用可能になるとすぐに表示されます。IsBusy 状態は必須ではありませんが、UI 関連の状態が非同期指向のコードに入る方法を示しています。
これが別の私に役立つことを願っています!