1

これが私のシナリオです。ボタン付きの単純な wpf ウィンドウがあります。ユーザーがボタンをクリックすると、別のウィンドウ (子ウィンドウと呼びましょう) を作成し、バックグラウンド スレッドに wpf ボタンを作成し、子ウィンドウに追加して子ウィンドウを表示します。このコードは次のとおりです。

        Button backgroundButton = null;
        var manualResetEvents = new ManualResetEvent[1];
        var childWindow = new ChildWindow();
        manualResetEvents[0] = new ManualResetEvent(false);
        var t = new Thread(x =>
        {
            backgroundButton = new Button { Content = "Child Button" };
            childWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(()                   => childWindow.MainPanel.Children.Add(backgroundButton)));
            manualResetEvents[0].Set();
        });
        t.SetApartmentState(ApartmentState.STA);
        t.Start();

        WaitHandle.WaitAll(manualResetEvents);
        childWindow.ShowDialog();

ShowDialog() を呼び出すと、「別のスレッドが所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。」というエラーが表示されます。このエラーは、子ウィンドウに追加されたボタンがバックグラウンド スレッドで作成されたため、このエラーが発生することがわかっています。質問: このエラーを回避し、バックグラウンド スレッドでボタンを作成するにはどうすればよいですか?

4

1 に答える 1

1

Dispatcher別のスレッドから親のウィンドウにアクセスする場合は、毎回使用する必要があります。私はあなたのスレッドの行動を見て、あなたが使用していますbackgroundButton。そのため、ステートメント内のボタンで何でもする必要がありますDispathcer.BeginIvoke[編集]スレッドアクションをこれに変更します

var t = new Thread(x =>
    {
        backgroundButton.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(()                   => backgroundButton = new Button { Content = "Child Button" }));
        childWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(()                   => childWindow.MainPanel.Children.Add(backgroundButton)));
        manualResetEvents[0].Set();
    });

私はあなたのコードに従ってこれを書きました.私はあなたのコードをチェックしませんが、それが正しいことを願っています.

于 2012-06-06T07:13:35.393 に答える