Разработка приложения Bluetooth для Raspberry Pi3 на Win IOT
Я новичок в разработке программного обеспечения для Windows IOT. У меня есть информация о.Net 3.5 и 4. Когда я начал разрабатывать для Win IOT, я увидел, что многое изменилось. Есть много новых слов async, await, Task и т. Д.
Теперь я хочу читать и записывать данные с Bluetooth. Я могу сделать это, но если я пытаюсь писать и читать данные в бесконечном цикле, это вызывает исключения.
У меня 2 функции
Читать:
private async Task ReadAsync(CancellationToken cancellationToken)
{
uint ReadBufferLength = 1024;
Task<UInt32> loadAsyncTask;
// If task cancellation was requested, comply
cancellationToken.ThrowIfCancellationRequested();
// Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
// Create a task object to wait for data on the serialPort.InputStream
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
// Launch the task and wait
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
receivedData = dataReaderObject.ReadString(bytesRead);
}
else
{
receivedData = "";
}
}
Написать:
private async Task SendData(string data)
{
if (deviceService != null)
{
//send data
if (string.IsNullOrEmpty(data))
{
uiTxtError.Text = "Please specify the string you are going to send";
}
else
{
//DataWriter dwriter = new DataWriter(streamSocket.OutputStream);
UInt32 len = dwriter.MeasureString(data);
dwriter.WriteUInt32(len);
dwriter.WriteString(data);
await dwriter.StoreAsync();
await dwriter.FlushAsync();
}
}
else
{
uiTxtError.Text = "Bluetooth is not connected correctly!";
}
}
Функция, использующая чтение и запись.
await SendData("010C" + Environment.NewLine);
await ReadAsync(ReadCancellationTokenSource.Token);
if (!string.IsNullOrEmpty(receivedData))
{
string[] splitted = receivedData.Replace("\r", "").Replace(">", "").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
int a = 0;
int b = 0;
if (int.TryParse(splitted[splitted.Length - 1], System.Globalization.NumberStyles.HexNumber, null as IFormatProvider, out b))
{
if(int.TryParse(splitted[splitted.Length - 2], System.Globalization.NumberStyles.HexNumber, null as IFormatProvider, out a))
{
uiGaugeRpm.Value = ((a * 256) + b) / 4;
}
}
receivedData = "";
}
Я вызываю функцию выше в бесконечном цикле с задержкой 200 мс (Task.Delay(200)).
ReadCancellationTokenSource = new CancellationTokenSource();
if (streamSocket.InputStream != null)
{
dataReaderObject = new DataReader(streamSocket.InputStream);
try
{
while (true)
{
await GetRPM();
await Task.Delay(200);
}
}
catch (Exception excp)
{
MessageDialog dialog = new MessageDialog(excp.Message);
await dialog.ShowAsync();
}
}
После запуска цикла он получает данные верными и корректными, но через несколько циклов он генерирует исключения.
Если я создаю объект datawriter в функции write, он генерирует необработанное исключение и останавливает приложение. Я решаю это путем создания этого объекта только один раз после подключения. Теперь я получаю новое исключение.
loadAsyncTask = dataReaderObject.LoadAsync (ReadBufferLength).AsTask (cancellationToken);
В этой строке я получаю ObjectDisposedException, я наблюдал за объектами, но не мог видеть ничего, что было удалено.
Я подключаюсь к устройству Bluetooth ELM327 с протоколом rfcomm. Я новичок в разработке для Win IOT.
Также я не смог использовать привязки с асинхронными функциями.
Пожалуйста, не могли бы вы помочь мне?
1 ответ
Да, к сожалению, это все о задачах сейчас. Потоки не доступны в рамках UWP. Только ядро.
Я бы предложил вам использовать пару тикеров, чтобы справиться с этим. 1 тикер для отправки и 1 для получения.
Например:
DispatcherTimer receiveTimer;
DispatcherTimer senderTimer;
//class MainPage : Page ... etc ...
private async Task SetupAsync()
{
this.bluetoothApp = await Bluetooth.CreateAsync();
this.receiveTimer = new DispatcherTimer();
this.receiveTimer.Interval = TimeSpan.FromMilliseconds(1000);
this.receiveTimer.Tick += this.ReceiveTimer_Tick;
this.receiveTimer.Start();
this.senderTimer = new DispatcherTimer();
this.senderTimer.Interval = TimeSpan.FromMilliseconds(1000);
this.senderTimer.Tick += this.SenderTimer_Tick;
this.senderTimer.Start();
}
Затем пара методов для каждого тикера:
private void ReceiveTimer_Tick(object sender, object e)
{
//Receive stuff
}
private void SenderTimer_Tick(object sender, object e)
{
//Send stuff
}
Наконец добавьте это на свою главную страницу:
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
await SetupAsync();
}