2

実行時に作成する必要がある非常に複雑な 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 サービスから取得されます。

これが、このメソッドの実行に予想よりも少し時間がかかる理由です。

4

2 に答える 2

1

Assembly世代をチャンクする必要があります。アセンブリの生成に時間がかかりすぎて、すべてを別のスレッドに配置する必要があり、同じスレッドで DIRECT Ui コンポーネントの生成のみを行う必要があります。

ストリームから Xaml を読み込んで、UI を詰まらせることなくチャンクで実行できるクールな方法があります。ご覧ください: http://msdn.microsoft.com/en-us/library/aa346591.aspx

于 2013-05-15T16:45:38.760 に答える