在C#中使用串口

时间:2013-01-10 09:33:14

标签: c# wpf multithreading

我正在使用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

2 个答案:

答案 0 :(得分:0)

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

所以要真正解决这个问题,你必须解耦数据接收和gui任务。在接收到的数据事件中,只需将接收到的数据放入某种列表,队列等中即可。在gui线程中,你经常看一下这个列表,排队(可能是通过使用一个计时器)并根据你得到的内容采取行动。

注意:如果您需要操作列表,从多个线程排队(例如在数据接收事件中添加项目,在gui计时器中删除项目),您应该查看{{3}并考虑使用Concurrent-namespaceTask Parallel Library

答案 1 :(得分:0)

尝试使用来自调用方法的调度程序类的BeginInvoke。此invoke方法在导致此错误的同一线程上调用。和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;
            }

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