LoginSignup
1
2

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-06-25

概要

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2