2014-01-06 3 views
0

Я наблюдаю странное поведение при попытке доступа к SerialPort через .NET framework. Я делаю это, чтобы перебрать все доступные COM-порты, отправить строку, прочитать ответ и закрыть порт. Целью является проверка того, какой порт подключен к устройству.Повреждение приложения Strange SerialPort

Теперь странное поведение: иногда приложение падает с ObjectDisposedException, а иногда и нет. Случайность этого наблюдения и тот факт, что я не могу поймать ObjectDisposedException, заставляет меня поверить, что проблема должна произойти в другом проступнике из моего контроля.

Мой вопрос: что может вызвать это исключение и что я могу сделать, чтобы избежать его?

Это полный код моего маленького тестового приложения, которое выходит из строя случайным образом два из трех испытаний:

private static void Main(string[] args) 
{ 
    try 
    { 
     var portnames = SerialPort.GetPortNames(); 
     foreach (var portName in portnames) 
     { 
      try 
      { 
       Console.WriteLine("Try Port {0}...", portName); 
       var serial = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One) 
        { 
         WriteTimeout = 500, 
         ReadTimeout = 500, 
         Handshake = Handshake.XOnXOff 
        }; 

       serial.Open(); 
       serial.WriteLine("foo bar"); 
       Thread.Sleep(500); 
       var responseBuffer = serial.ReadLine(); 
       serial.Close(); 

       Console.WriteLine(" >> Port {0} responded: {1}", portName, responseBuffer); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(" >> Port {0} exception: {1}", portName, ex.Message); 
      } 
     } 
    } 
    catch (ObjectDisposedException ode) 
    { 
     // this never happens but the app crashes with an ObjectDisposedException 
     Console.WriteLine("yea, got you!"); 
    } 

    Console.WriteLine("finished checking ports..."); 
    Console.ReadKey(); 
} 

Она также может быть проблемой драйвера на моем компьютере, но все же, что я мог сделать, чтобы avoide приложение? Я на самом деле поймать AppDomain.CurrentDomain.UnhandledException(object sender, UnhandledExceptionEventArgs e), но тогда e.ExceptionObject.IsTerminating является true и приложение завершает работу в любом случае ...

EDIT:

Как я сказал, я не могу поймать исключение непосредственно, то, что я пост здесь является StackTrace из объекта исключения, который передается событию AppDomain.CurrentDomain.UnhandledException. Я могу войти это, но так как этот объект исключения IsTerminating я ничего не могу сделать полезным вместе с ней

bei System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) 
    bei System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success) 
    bei Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait) 
    bei System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent() 
    bei System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    bei System.Threading.ThreadHelper.ThreadStart() 
+1

Столбец был бы полезен – leppie

+0

Этот поток запускается, когда порт открыт. Я думаю, что это не очень потокобезопасно, когда другая программа также пытается получить доступ к порту. Это может быть связано с тем, что «SerialPort» является «Компонентом» и, возможно, требует запуска под коннетом сообщений Windows, в приложении WinForms. – leppie

+0

это тестовое приложение - просто консольное приложение, целевое приложение - это приложение wpf, в котором происходит одна и та же ошибка. Я попробую этот фрагмент кода в приложении форм позже. Тем не менее, есть ли у вас какая-либо ссылка, чтобы указать мне, как запустить этот фрагмент в цикле сообщений (с учетом приложения wpf)? –

ответ

1

При исследовании проблемы утечки памяти, связанной с классом SerialPort Я наткнулся на этот пост: .NET SerialPort Woes

Вы упомянули ObjectDisposedException, статья в основном касается IOExceptions, поэтому я не уверен, связана ли ваша проблема. Однако в конце статьи есть решение для исключения IO, которое вы могли бы попробовать:

Как вы это исправите? Просто. Прежде чем вы вызовете SerialPort.Open(), просто откройте последовательный порт, вызвав функцию CreateFile и SetCommState fAbortOnError на false. Теперь вы можете безопасно открыть последовательный порт, не опасаясь, что он может вызвать исключение IOException.

+0

Спасибо за ответ. К счастью, мы нашли способ полностью обойти последовательный порт и использовать более стабильное соединение tcp. Так что, честно говоря, я не найду времени, чтобы исследовать это больше ... –

Смежные вопросы