0

私はWPFで作業しています。Dispatcher を使用して、メインの xaml ウィンドウでスレッド プロセスを実行します。

次に、別の WPF を開いて 3D 画像を表示した結果を表示すると、次のエラーが発生しました。

{"多くの UI コンポーネントがこれを必要とするため、呼び出しスレッドは STA でなければなりません。"}

これは、新しいウィンドウを開始する方法です。

void DisplayFormThread()
{
    IResult result = _mainWindow.GetResult();
    ResultView resultView = new ResultView (result);
    resultView.Show();
}

これをstackoverflowのいくつかの投稿に追加して問題を解決しようとしましたが、役に立ちません:

ThreadStart start = delegate()
{
   DispatcherOperation op = Dispatcher.CurrentDispatcher.BeginInvoke(
        new delegateNewWindow(DisplayFormThread), DispatcherPriority.Background);

        DispatcherOperationStatus status = op.Status;
                   while (status != DispatcherOperationStatus.Completed)
                   {
                            status = op.Wait(TimeSpan.FromMilliseconds(1000));
                            if (status == DispatcherOperationStatus.Aborted)
                            {
                                 // Alert Someone
                            }
                    }

       };

// Create the thread and kick it started!
Thread thread = new Thread(start);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

どうすれば問題を解決できますか?

前もって感謝します。

4

3 に答える 3

3

その理由は、新しく作成されたスレッドが WPF ウィンドウ インフラストラクチャをサポートするために有効になっていないためです。特に、Windows メッセージ ポンピングはサポートされていません。新しく作成されたウィンドウに対して別のディスパッチャを実行する必要があります。これはこれのサンプルです

于 2012-04-23T09:15:52.153 に答える
2

WPF では、スレッドが STA タイプである必要があるため、DisplayFormThread を STA スレッドで呼び出す場合は、次のようにする必要があります。

Thread newThread = new Thread(new ThreadStart(DisplayFormThread));
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();

STAThread は、現在の (メイン) スレッドで使用されるスレッド モデルを指す「シングル スレッド アパートメント」を指します。基本的に、[STAThread] 宣言を使用すると、他のアプリケーションは、データを送信するときにスレッドのポリシーが何であるかを知ることができます。STA モデルは、Windows スレッド/アプリケーションの最も一般的なスレッド モデルです。Apartment State の詳細については、こちらをご覧ください。

于 2012-04-23T08:13:43.103 に答える
0

UI オブジェクトはシングル スレッド アパートメント (sta) で宣言する必要があり、STA スレッドごとに新しいディスパッチャを作成する必要があります。

Dispatcher.Run()スレッド開始のアクション パラメータ内で呼び出す必要があります

ThreadStart start = delegate() {
    DispatcherOperation op = Dispatcher.CurrentDispatcher.BeginInvoke(
    new delegateNewWindow(DisplayFormThread), DispatcherPriority.Background);

    DispatcherOperationStatus status = op.Status;
    while (status != DispatcherOperationStatus.Completed) {
        status = op.Wait(TimeSpan.FromMilliseconds(1000));
        if (status == DispatcherOperationStatus.Aborted) {
            // Alert Someone
        }
    }
    Dispatcher.Run();
};

// Create the thread and kick it started!
Thread thread = new Thread(start);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

ディスパッチャーは複数の UI スレッド間のデータ共有を管理するため、WPF UI スレッドにはディスパッチャーが必要です。

于 2020-05-20T14:08:58.703 に答える