Stop Stream.BeginRead()

前端 未结 3 1538
旧时难觅i
旧时难觅i 2021-01-19 03:38

i need to read data from my virtual com port and detect the message \"Dreq\". Once i press the connect button, it connects to my COM8 port and begins reading in a new thread

3条回答
  •  -上瘾入骨i
    2021-01-19 04:03

    It's an old post, but I think this solution can help people with the same problem.

    I was using legacy code for an application and I found that the problem with BeginRead and EndRead is that there is no way to cancel the asynchronous operation. Therefore, when you close the port, your call to BeginRead stays there forever until another byte is received in the port, then your call to EndRead will free up the port. If it does not happen this way, then your application may hang and not even task manager can close it until you unplug the serial port cable!

    Fortunately the TPL library can fix this problem in a very simple and elegant way. The CancelToken is what you need:

    On port open:

    while (x)   
       var myTask = _serialPort.BaseStream.ReadAsync(_serialBuffer, 0, _bufferLength, cancelToken.Token);
       var bytesRead = await myTask;
       ... your business logic here... 
        if ((myTask.IsCanceled) || (myTask.IsFaulted)) break;
    }
    

    On port close:

    cancelToken.Cancel(false);
    

    Please note a while loop is better than recursive call because when port is broadcasting lots of information, a stack overflow exception is thrown after 15 minutes.

    It's a very simple implementation. I hope it helps

提交回复
热议问题