0

我在我的 WPF 应用程序中使用串行端口,并且日志文件中有许多错误,例如“没有足够的配额来处理此命令”。

这个来源我认为有问题。我的错误在哪里?

void barcodeSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        string code = barcodeSerialPort.ReadLine();

        this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
        {                
            if (new DateTime(model.ComebackDate.Year, model.ComebackDate.Month, model.ComebackDate.Day) > DateTime.Now)
            {
                new WndMessage("Date time error...").ShowDialog();
                Switcher.Switch(new MainMenu());
                return;
            }

            // ...............
        });       

10.01.2013 10:05:08 - Exception on UI Thread (Dispatcher)
Exception message - There is not enough quota to process this command
Source - WindowsBase
StackTrace -    at MS.Win32.UnsafeNativeMethods.PostMessage(HandleRef hwnd, WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
   at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(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)
TargetSite -Void PostMessage(System.Runtime.InteropServices.HandleRef, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr)
InnerException.Message - NULL
4

2 回答 2

0

尝试使用调度程序类中的 BeginInvoke 而不是调用方法。此调用方法在导致此错误的同一线程上调用。和 beginInvoke 方法会将对象分派到 UI 线程队列中,这将正常工作。

尝试使用它。

 this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)delegate()
        {                
            if (new DateTime(model.ComebackDate.Year, model.ComebackDate.Month, model.ComebackDate.Day) > DateTime.Now)
            {
                new WndMessage("Date time error...").ShowDialog();
                Switcher.Switch(new MainMenu());
                return;
            }

            // ...............
        });     
于 2013-01-10T12:16:39.780 回答
0

接收到的数据事件将在它自己的线程中触发,并通过调用Dispatcher.Invoke()您调用每次此事件被触发回 gui 线程并在该方法中您将调用一个ShowDialog()将暂停直到此对话框关闭,这将暂停您的调度程序,它将暂停您的数据接收线程。

所以要真正解决这个问题,你必须将数据接收和 gui 任务解耦。在数据接收事件中,只需将接收到的数据放入某种列表、队列等中,仅此而已。在 gui 线程中,您会定期查看此列表、排队(可能使用计时器)并根据您得到的内容采取行动。

注意:如果您需要操作列表,从多个线程排队(例如在数据接收事件中添加项目,在 gui 计时器中删除项目),您应该查看Concurrent-namespace并考虑任务并行库的使用或反应式扩展

于 2013-01-10T09:56:31.467 回答