代表们没有阻止大爆炸 [英] Delegates not preventing the big explosion

查看:52
本文介绍了代表们没有阻止大爆炸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我首先在这里提到了Com Port DataReceived事件的问题:

I first mentioned my problem with a Com port DataReceived event here:

http://social.msdn. microsoft.com/Forums/zh-CN/csharpgeneral/thread/b7437518-2a98-488c-9e96-cccbc8bf9c31/

从那时起,我尝试了代理路线,但它也炸毁了.这是我添加的仍然无法解决问题的代码:

Since then, I tried the delegate route, but it also blows up. Here's the code I added that still doesn't do the trick:

1)
为从com端口的DataReceived事件中调用的方法创建了两个委托:

1)
Created two delegates for the methods called from within the com port's DataReceived event:

      公共委托void SendToRS232_1Delegate(string AStringToSend); //<-原始方法被标记为私有.不应该吗?
      公共委托void LogDelegate(LogMsgType msgtype,字符串msg);

        public delegate void SendToRS232_1Delegate(string AStringToSend); // <-- original method is marked private. should it not be?
        public delegate void LogDelegate(LogMsgType msgtype, string msg);

2)
更改了DataReceived()事件:

2)
Changed the DataReceived() event:

       //当端口的缓冲区中有数据等待时,将触发此事件.
       private void port_DataReceived1(对象发送者,SerialDataReceivedEventArgs e)
       {
          字符串s = string.Empty;
          字符串sData = string.Empty;
           //根据对上面引用的线程的响应尝试委托;使用专业C#4和.NET4" p. 492-3为基础
           LogDelegate ld =日志;
           IAsyncResult ar = ld.BeginInvoke(LogMsgType.Normal,string.Format("port_DataReceived1()在{0}被调用,DateTime.Now.ToLocalTime()),null,null);
           ld.EndInvoke(ar); //<-在新的代码部分中,它显然炸毁了
          试试
           {
                             //如果com端口已关闭,则不执行任何操作
                            如果(!port1.IsOpen)
                             {
                    //2Log(LogMsgType.Warning,string.Format("{0}被发现在{1}关闭,试图重新打开...",
              //sArrCOMPorts [0],DateTime.Now.ToLocalTime()));
                   试试
                    {
               b port1.Open();
                    }
                    catch(异常例外)
                    {
               b //3Log(LogMsgType.Error,string.Format(
              nbsp; bsp   //尝试打开端口1:{0},堆栈跟踪:({1}),内部异常:{{2})在{3}时遇到错误",
              nbsp; bsp     //   ex.Message,ex.StackTrace,ex.InnerException,DateTime.Now.ToLocalTime()));
               b返回;
                    }
                             }
                             //读取缓冲区中等待的所有数据
                            如果(port1.BytesToRead> 0)
                             {
                    sData = port1.ReadExisting();
                    //MessageBox.Show(string.Format("Existing data = {0},sData)); <-确实工作了几次,但我确实希望将其写入StackPanel
                             }
                            其他
                             {
                   返回;
                             }

        // This event fires when there is data waiting in the port's buffer.
        private void port_DataReceived1(object sender, SerialDataReceivedEventArgs e)
        {
            string s = string.Empty;
            string sData = string.Empty;
            // Tried delegates based on response to thread referenced above; used "Professional C#4 and .NET4" p. 492-3 as basis
            LogDelegate ld = Log;
            IAsyncResult ar = ld.BeginInvoke(LogMsgType.Normal, string.Format("port_DataReceived1() was called at {0}", DateTime.Now.ToLocalTime()), null, null);
            ld.EndInvoke(ar); // <-- It apparently blows up here in this new section of code
            try
            {
                // If the com port has been closed, do nothing
                if (!port1.IsOpen)
                {
                    //2Log(LogMsgType.Warning, string.Format("{0} was found to be closed at {1}, attempting to reopen...",
                       // sArrCOMPorts[0], DateTime.Now.ToLocalTime()));
                    try
                    {
                        port1.Open();
                    }
                    catch (Exception ex)
                    {
                        //3Log(LogMsgType.Error, string.Format(
                           // "Error encountered attempting to open port1: {0}, StackTrace: ({1}), Inner Exception: ({2}) at {3}",
                             //   ex.Message, ex.StackTrace, ex.InnerException, DateTime.Now.ToLocalTime()));
                        return;
                    }
                }
                // Read all the data waiting in the buffer
                if (port1.BytesToRead > 0)
                {
                    sData = port1.ReadExisting();
                    //MessageBox.Show(string.Format("Existing data = {0}", sData)); <-- this did work a few times, but I really want it written to the StackPanel
                }
                else
                {
                    return;
                }

               //在终端中向用户显示文本;如果需要先解析,
                             //在这里做...
                             //4Log(LogMsgType.IncomingCom1,sData);

                // Display the text to the user in the terminal; if needs to be parsed first,
                // do that here...
                //4Log(LogMsgType.IncomingCom1, sData);

               //如果是Ack Msg,则类型为"N"的消息(负数,未成功收到)应该
                             //至少发送两次(共3次).如果认为很关键,可以
                             //继续重新发送,但是在第三次失败后,味精类型为"E". (错误)已发送.
                             //那么,我推断出接收者有责任跟踪有多少人
                             //它发送了"N"次的次数-我们不必为此目的.只要是"N"
                             //我们一直在尝试重新发送;如果是"E",则仅在它是关键"邮件时才尝试重新发送.味精
                            如果(ssu.IsAcknowledgementMessage(sData))
                             {
                    if(sData [SortSimUtils.ACK_MSG_TYPE_POS] .ToString().Equals("N"))
                    {
               b //我们可以假设要重发的味精是给定的最后一个味精
               b //序列号?请问回复"是否会快来吗?
               b int iSeqNum = ssu.GetSequenceNumber(sData);
               b SendToRS232_1代理str1d = SendToRS232_1;
               b IAsyncResult ar2 = str1d.BeginInvoke(sData,null,null);
               b str1d.EndInvoke(ar2);
               b //SendToRS232_1(ssu.GetLastAckMsgWithSeqNum(iSeqNum));
                    }
                   否则if(sData [SortSimUtils.ACK_MSG_TYPE_POS] .ToString().Equals("E"))
                    {
               b //如果紧急,请重新发送,否则忽略(log)
               b如果(ssu.IsCriticalAckMsg(sData))
               b {
              nbsp; bsp    SendToRS232_1(sData); //如有必要,请在此处复制委托代码;暂时不需要,因为 IsCriticalAckMsg()仅返回false
               b }
               b其他
               b {
              nbsp; bsp    //5Log(LogMsgType.Warning,string.Format(
              nbsp; bsp      //返回非关键性Ack消息,错误代码:{0}",sData));
               b }
                    }
                             }
           }
           catch(异常例外)
           {
                             s = ex.Message;
                             MessageBox.Show(s);
                             //6Log(LogMsgType.Error,ex.Message);
           }
           //最后
           //{
           //    //7Log(LogMsgType.Error,s);
           //}
       }

                // If an Ack Msg, those of type "N" (negative, not received successfully) should
                // be resent at least twice (so, a total of 3 times). If considered critical, can
                // continue to be resent, but after third failure, a msg type "E" (error) is sent.
                // I'm deducing, then, that it is the recipient's duty to keep track of how many
                // times it has sent "N" - we don't have to on this end. As long as it's "N"
                // we keep trying to resend; if "E", we only try to resend if it is a "Critical" msg
                if (ssu.IsAcknowledgementMessage(sData))
                {
                    if (sData[SortSimUtils.ACK_MSG_TYPE_POS].ToString().Equals("N"))
                    {
                        // Can we assume that the msg to resend is the last one with the given
                        // sequence number? Will the "reply" come that quickly?
                        int iSeqNum = ssu.GetSequenceNumber(sData);
                        SendToRS232_1Delegate str1d = SendToRS232_1;
                        IAsyncResult ar2 = str1d.BeginInvoke(sData, null, null);
                        str1d.EndInvoke(ar2);
                        //SendToRS232_1(ssu.GetLastAckMsgWithSeqNum(iSeqNum));
                    }
                    else if (sData[SortSimUtils.ACK_MSG_TYPE_POS].ToString().Equals("E"))
                    {
                        //if critical, resend, otherwise ignore (log)
                        if (ssu.IsCriticalAckMsg(sData))
                        {
                            SendToRS232_1(sData); //If necessary, duplicate delegate code here; not necessary for now, as IsCriticalAckMsg() simply returns false
                        }
                        else
                        {
                            //5Log(LogMsgType.Warning, string.Format(
                               // "Non-critical Ack msg returned Error code: {0}", sData));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                s = ex.Message;
                MessageBox.Show(s);
                //6Log(LogMsgType.Error, ex.Message);
            }
            //finally
            //{
            //    //7Log(LogMsgType.Error, s);
            //}
        }

推荐答案

Hy Clay.

Hy Clay.

您正在使用委托的调用功能,而不是目标控件的调用功能.

You are using the invoke function of the delegate, not of the target control.

看看我对您以前的想法的答复.

Take a look at my response on your previous thred.


这篇关于代表们没有阻止大爆炸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆