概要
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()
が終了しないということが発生する。
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