/// <summary> /// Perform functions in form from a different thread. See AccessFormMarshal. /// </summary> /// <remarks> /// Based on methods used by Jan Axelson in Serial Port Complete 2nd edition. I break it out a little further /// as I handle exceptions seperately. /// </remarks> /// <param name="userInterfaceAction">Enum that indicates which action to perform</param> /// <param name="comPortData">Com Port data being returned if applicable</param> private void AccessForm(ComPort.ComPortEvent userInterfaceAction, string comPortData) { switch (userInterfaceAction) { case ComPort.ComPortEvent.ReturnNewData: //Retrieve new com port data. ProcessReloadData(comPortData); break; case ComPort.ComPortEvent.ReportStatus: //Display ComPort status. comPortStatusLabel.Text = comPortData; break; case ComPort.ComPortEvent.ReportException: //Exception occured in ComPort. MessageBox.Show(comPortData, "Exception Occurred", MessageBoxButtons.OK, MessageBoxIcon.Error); break; case ComPort.ComPortEvent.ReportSerialError: //Serial error occured in ComPort. comPortErrorsTextBox.AppendText(DateTime.Now.ToString() + " - " + comPortData + Environment.NewLine); break; } }
/// <summary> /// Enables accessing the form from another thread. The parameters match those of AccessForm. /// </summary> /// <remarks> /// Based on methods used by Jan Axelson in Serial Port Complete 2nd edition, except I use /// BeginInvoke rather than Invoke, to avoid the deadlock issue. /// </remarks> /// <param name="userInterfaceAction">Enum that indicates which action to perform</param> /// <param name="comPortData">Com Port data being returned if applicable</param> private void AccessFormMarshal(ComPort.ComPortEvent userInterfaceAction, string comPortData) { AccessFormMarshalDelegate accessFormMarshalDelegate = new AccessFormMarshalDelegate(AccessForm); object[] args = { userInterfaceAction, comPortData }; //Call AccessForm, passing the parameters in args. I use BeginInvoke, after reading several sources indicating //it should be used to avoid a deadlock when the port is closed. Initially I saw it in Alex F.'s comments here: //http://forums.codeguru.com/showthread.php?516248-RESOLVED-Serial-port-hangs-on-form-close, more explanation here: //http://blogs.msdn.com/b/bclteam/archive/2006/10/10/top-5-serialport-tips-_5b00_kim-hamilton_5d00_.aspx. I'm not //sure if there are any downsides yet, but it fixed the deadlock for me, and everything still seems to work okay. base.BeginInvoke(accessFormMarshalDelegate, args); }