2016-08-11 61 views
1

UIスレッドから長時間実行タスク(T1)をプロセスとして起動し、その完了を待ちます。 T1は、ユーザーが手動で終了した場合にのみ終了します。ユーザーがそのタスクを閉じないと、UIスレッドはwhileループで待機し続けます。 10-15時間後、以下の例外を除いてメインプログラムが終了する。私の理解によると、UIディスパッチャーはprocess.WaitForExit(300000)でビジー状態であるため、メッセージキューを処理することができず、かなりの時間が経過するとキューがいっぱいになるためです。私は、UIディスパッチャのメッセージキューをどのようにクリアして、長時間放置しても例外がスローされないようにしたいのですが、UI Dispatcherメッセージキューがいっぱいになる

これは、UIスレッドで長時間実行されるタスクを起動するための良い方法ではないことがわかっています。バックグラウンドワーカーを使用できます。 WPFアプリケーションで

UIスレッド

  // Stop the process from opening a new window 
      System.Diagnostics.Process process = new System.Diagnostics.Process(); 
      process.StartInfo.RedirectStandardOutput = true; 
      process.StartInfo.UseShellExecute = false; 
      process.StartInfo.CreateNoWindow = true; 

      // Setup executable and parameters 
      process.StartInfo.FileName = "Some .exe path"; 
      process.StartInfo.Arguments = args; 
      process.StartInfo.RedirectStandardOutput = false; 
      process.StartInfo.RedirectStandardError = false; 


      if (false == process.Start()) 
      { 
       return false; 
      } 

      while (!process.WaitForExit(300000)) 
      { 
       // here I want to Process Dispather queue tasks if any present so that the queue does not become full 
      }` 

生成されます例外:

Exception Info: System.ComponentModel.Win32Exception 
Stack: 
   at MS.Win32.UnsafeNativeMethods.PostMessage(System.Runtime.InteropServices.HandleRef, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr) 
   at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean, System.Nullable`1) 
   at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr) 
   at System.Windows.Interop.HwndTarget.HandleMessage(MS.Internal.Interop.WindowMessage, IntPtr, IntPtr) 
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) 
   at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) 
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object) 
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) 
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) 
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32) 
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr) 
   at System.Threading.SynchronizationContext.WaitHelper(IntPtr[], Boolean, Int32) 
   at System.Windows.Threading.DispatcherSynchronizationContext.Wait(IntPtr[], Boolean, Int32) 
   at System.Threading.SynchronizationContext.InvokeWaitMethodHelper(System.Threading.SynchronizationContext, IntPtr[], Boolean, Int32) 
   at System.Threading.WaitHandle.WaitOneNative(System.Runtime.InteropServices.SafeHandle, UInt32, Boolean, Boolean) 
   at System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64, Boolean, Boolean) 
   at System.Threading.WaitHandle.WaitOne(Int32, Boolean) 
   at System.Diagnostics.Process.WaitForExit(Int32) 

答えて

0

あなたは、ドキュメントによるとawait Dispatcher.Yield(DispatcherPriority.ApplicationIdle)
を使用することがあります:非同期バックにコントロールを生成するawaitableオブジェクトを作成します。 現在のディスパッチャ。ディスパッチャが他のイベントを処理する機会を提供します。

0

代わりにprocess.Exitedイベントを使用しないでください。ブロックされませんか?

+0

処理が完了するまでお待ちしています。それ以降のすべてのアクションは、プロセス終了コードなどの値に依存します。 – amitasviper

+0

イベントハンドラのコードでこれ以上のアクションを実行できないのはなぜですか?発信者にコードを返す必要がありますか?コールバックはそれを処理できますか? – aQsu

関連する問題