Edited at

[UWP] SerialDeviceのDisposeが終了しない場合の回避策

More than 1 year has passed since last update.


概要

Raspberry Pi 3 + Windows IoT + UWPの環境において、SerialDeviceのDispose()が終了しない問題が発生した。

この回避策を述べる。


発生した環境


  • Raspberry Pi 3 Model B

  • Windows 10 IoT

  • Microsoft.NETCore.UniversalWindowsPlatform 6.0.6 & 6.1.5

  • USB-UART変換ケーブル


現象

Raspberry Pi 3 + Windows IoT + UWPの環境において、以下のコードを定期的に実行しながら、そのUART0に向けてシリアル通信で外部から送信を続けると、時折、serialDevice.Dispose()が終了しないということが発生する。


hang.cs

var serialDevice = await SerialDevice.FromIdAsync(id);

serialDevice.BaudRate = ...
serialDevice.DataBits = ...
serialDevice.Parity = ...
serialDevice.StopBits = ...
serialDevice.Handshake = ...

var dataWriter = new DataWriter(serialDevice.OutputStream);
var dataReader = new DataReader(serialDevice.InputStream);

uint size = await dataReader.LoadAsync(256);
if (size > 0)
{
var buffer = new byte[size];
dataReader.ReadBytes(buffer);
}

System.Diagnostics.Debug.WriteLine("Disposing");
serialDevice.Dispose();
dataWriter.Dispose();
dataReader.Dispose();
System.Diagnostics.Debug.WriteLine("Disposed");


また、Dispose()の順序をDataWrtier/DataReaderを先にした場合、先にDisposeした部分で同様の問題が発生する。


解決策

Dispose前で100ms待機する。

await Task.Delay(100);

serialDevice.Dispose();
dataWriter.Dispose();
dataReader.Dispose();

これを追加して以来、Disposeが終了しない問題は起きていない。

なぜこれで解決するのかはわからない。興味がある人は下記リンクにあたってほしい。

ひとつめのリンクが100ms待機するという対応を教えてくれたソースであり、その情報が根拠としているのがふたつめのリンク(こちらはUWPではない.NET環境のSerialPortクラスの情報)になっている。


参考にした情報

Windows IoT BackgroundTask Async/Await

https://stackoverflow.com/questions/44893263/windows-iot-backgroundtask-async-await

Why Thread.Sleep() before SerialPort.Open and Close?

https://stackoverflow.com/questions/6434297/why-thread-sleep-before-serialport-open-and-close/14313505