dotMorten / NmeaParser

Library for handling NMEA message in Windows Desktop, Store, Phone, Universal, and Xamarin (Android + iOS), coming from files, bluetooth, serial port or any stream
https://dotmorten.github.io/NmeaParser/
Apache License 2.0
262 stars 89 forks source link

NmeaParser.CloseAsync does not close the underlying socket stream correctly. #12

Closed mb12 closed 9 years ago

mb12 commented 9 years ago

How to reproduce the problem?

device =..............<Boiler plate code to create device >
await device.OpenAsync();
await device.CloseAsync()
....
.....
device = .... .<Boiler plate code to create device >

At this point you will get an exception like this. System.Exception: Only one usage of each socket address (protocol/network address/port) is normally permitted. Bluetooth

Issue in NmeaDevice.StartParser that's causing this and how to fix it.

  1. The issue is that CloseAsync will be called on the UI thread and set m_cts.token.IsCancellationRequested property to true.
  2. Once the m_cts.token.IsCancellationRequested is set to true, any code that does await Task.Delay(50, token) is going to throw TaskCancelledException
  3. Once the exception is thrown closeTask.SetResult(true) will not execute.

To fix this one could explicitly handle the TaskCancelledException or instead of using the cancellation token use a new data member cancelled.

dotMorten commented 9 years ago

@mb12 Thanks for the issue, but could you provide a little more detail? There seems to be a lot of code snippets missing. What's the device code? Could you provide a fully compiling piece of code to repro the issue with?

Wrt to (2), are you saying you don't expect a cancellation exception to happen when you cancel a task? That's how the task framework works.

mb12 commented 9 years ago

@dotMorten Thank you very much for the response and creating this fantastic and easy to use library that works well with Windows Store apps. I've included details below.

1.) The scenario is:

I was emulating this via a toggle open/close button in the sample test app.

2.) TaskCancelledException is expected to happen and is correctly thrown. But in this case it also prevents this line of code from running. This in turn this means continuation routine of closetask at this line will never kick in. This in turn would prevent the underlying stream from closing.

dotMorten commented 9 years ago

What device are you using? Could you please provide full code that reproduces the problem? I'm not able to reproduce what you're doing without knowing what code you're writing. A unit test or sample app would be helpful

reasra commented 8 years ago

@dotMorten I've got a very similar problem but haven't spent any time tracking down this "TaskCancelledException" yet. I was, however, easily able to reproduce the problem by calling StartDevice(), StopDevice(), and StartDevice() again in the attached new 2.txt file. The second OpenAsync() will always throw "permission denied" because it never closes properly. new 2.txt