UI Dispatcher消息队列已满

时间:2016-08-11 12:45:39

标签: c# wpf multithreading dispatcher postmessage

我从UI线程启动一个长时间运行的任务(T1)作为进程并等待其完成。 T1仅在用户手动关闭时退出。如果用户没有关闭该任务,那么UI线程会在while循环中继续等待。 10-15小时后,主程序退出,下面给出例外情况。根据我的理解,这种情况正在发生,因为UI Dispatcher忙于process.WaitForExit(300000),因此无法处理消息队列,并且在相当长的时间后队列变满。我想问一下如何清除UI调度程序消息队列,以便在长时间运行时不会抛出异常。

我知道这不是在UI线程上启动长时间运行任务的好方法,我们可以使用Background Worker。

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)

2 个答案:

答案 0 :(得分:0)

您可以使用<!--jQuery core code--> <script src="{% static 'recipes/js/jquery-3.1.0.min.js' %}"></script>
根据文档:创建一个等待对象,异步控制回到 当前的调度员并为调度员提供处理其他事件的机会

答案 1 :(得分:0)

为什么不使用process.Exited事件,所以它不会阻止?