実行時に作成する必要がある非常に複雑な UserControl があります。この作成により、GUI が約 5 秒間フリーズします (これは許容できません)。
この操作をバックグラウンド ワーカーに移動しようとしたところ、次の例外が発生しました。
多くの UI コンポーネントがこれを必要とするため、呼び出しスレッドは STA でなければなりません。
MTA スレッドを使用して UserControl / UI Element を作成できないことは承知しています。BackgroundWorker と Dispatcher を組み合わせて使用しようとしましたが、うまくいきませんでした。
初挑戦
private void LetsGo()
{
var backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
DispatcherOperation dispatcherOperation = Dispatcher.CurrentDispatcher.BeginInvoke(new Action(this.GenerateControlAsync), DispatcherPriority.Background);
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
// Cancelled
}
else if (e.Error != null)
{
//Exception Thrown
}
else
{
//Completed
}
}
private void GenerateControlAsync () {
this.Control = new TimeConsumingUserControl();
}
上記のコードは機能していません。メソッド this.GenerateControlAsync は実行されません。
2 回目の試行
private async void GenerateControl()
{
this.Control = await Dispatcher.CurrentDispatcher.InvokeAsync<UserControl>(this.GenerateControlAsync);
}
private UserControl GenerateControlAsync()
{
return new TimeConsumingUserControl();
}
このサンプルは機能していますが、GUI スレッドがフリーズし続けます。
私は WPF と .net Framework 4.5 を使用しています。
メソッド GenerateControlAsync() は単純に UserControl のインスタンスを作成するのではなく、さらに多くのロジックが含まれていることに注意してください。
@ HighCoreの質問に答えるには: 実際、UserControl の XAML コードは XSLT を介して xml ファイルから変換され、分離コードは CodeDOM を使用して生成されます。全体をコンパイルしてアセンブリにラップする必要があります。assembly.CreateInstance() を使用して UserControl のインスタンスを取得します。この行は、引用された例外をスローします。私の GUI には、ViewModel の UserControl にバインドされた ContentControl があります。変換が必要な xml ファイルなどの生成用データは、Web サービスから取得されます。
これが、このメソッドの実行に予想よりも少し時間がかかる理由です。