0

アプリケーションが何らかの計算を行っているときに表示したいビジー インジケーターがあります。

var uiThread = new Thread(() =>
    {
        autoResetEvent.Set();
        bussyWindowVM.Dispatcher = Dispatcher.CurrentDispatcher;
        Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate
            {
                var busyWindow = new BusyWindow
                {
                    DataContext = bussyWindowVM, 
                    Owner = Application.Current.MainWindow,
                    WindowStartupLocation = WindowStartupLocation.CenterOwner
                };
                busyWindow.Show();
            });

        Dispatcher.Run();
    });
// set single threaded apartment
uiThread.SetApartmentState(ApartmentState.STA);

// mark UI thread as background thread
uiThread.IsBackground = false;

// start the UI thread
uiThread.Start();

// wait until thread exits
autoResetEvent.WaitOne();

しかし、アプリケーションを実行するとスローされます

System.InvalidOperationException "{別のスレッドが所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。}"

この問題を解決する方法がわかりません。

しかし、削除するOwner = Application.Current.MainWindowとすべて正常に動作しますが、所有者が正しく設定されていないため、アプリケーションのサイズを変更すると、ウィンドウがアプリケーションの中心にもなりません。

スタックトレース:

   at System.Windows.Threading.DispatcherObject.VerifyAccess()
   at System.Windows.Application.get_MainWindow()
   at MyProject.MyViewModel.<>c__DisplayClass3.<CreateBusyWindow>b__2() in D:\MyStuff\Dev\Repo\MyProject\ViewModels\MyViewModel.cs:line 2482
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at CivilGeo.GeoHECRAS.ViewModels.GeoHECRASViewModel.<>c__DisplayClass3.<CreateBusyWindow>b__1() in D:\MyStuff\Dev\CivilGeoRepo\GeoHECRAS\CivilGeo.GeoHECRAS\ViewModels\GeoHECRASViewModel.cs:line 2492
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
4

1 に答える 1

1

Dispatcher.CurrentDispatcherバックグラウンドスレッドで、そのスレッドの新しいDispatcherものを作成します。
このディスパッチャーは、元の UI スレッドのオブジェクト ( など) にアクセスできませんApplication.Current.MainWindow

別の UI スレッドを実行する場合は、設定できませんOwner。また、電話してはいけませんBeginInvoke()

于 2012-12-04T17:34:03.620 に答える