【问题标题】:Developing Bluetooth App For Raspberry Pi3 on Win IOT在 Win IOT 上为 Raspberry Pi3 开发蓝牙应用程序
【发布时间】:2016-09-09 21:27:36
【问题描述】:

我是为 Windows IOT 开发软件的新手。我有关于 .Net 3.5 和 4 的信息。当我开始为 Win IOT 开发时,我发现很多事情都发生了变化。生词async、await、Task等很多。

现在我想从蓝牙读写数据。我可以做到,但如果我尝试在无限循环中写入和读取数据,则会引发异常。

我有两个功能

阅读:

    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();
            }


        }

循环开始后,它得到的数据是正确的,但在几个循环之后它会抛出异常。

如果我在写入函数中创建数据写入器对象,它会引发未处理的异常并停止应用程序。我通过在连接后仅创建一次此对象来解决此问题。现在我得到了新的例外。

loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);

在这一行我得到了 ObjectDisposedException,我观察了对象,但看不到任何已处理的东西。

我正在使用 rfcomm 协议连接到 ELM327 蓝牙设备。我是为 Win IOT 开发的新手。

我也不能使用带有异步函数的绑定。

拜托,你能帮帮我吗?

【问题讨论】:

  • 这个例外对我来说似乎很清楚。您正在尝试使用已处置的对象。如果您需要这里的帮助,您需要提供一个好的minimal reproducible example 以可靠地重现问题。另请参阅How to Ask,了解如何以清晰、可回答的方式提出您的问题。

标签: c# raspberry-pi3 windows-10-iot-core rfcomm .net-4.5.2


【解决方案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();
}

【讨论】:

  • 我在我的电脑上尝试了相同的应用程序。我开发了一个虚拟 elm327 应用程序。它发送速度、转速和温度数据。我有一个蓝牙模块。我将其 TTL 端与 FTDI 芯片连接,将蓝牙端与蓝牙连接。 TTL 端为命令发送数据。同样的事情发生在我的电脑上。最初几秒钟,我的应用程序获取数据并将其显示在仪表上。稍后,发生 System.ObjectDisposedException。我不明白为什么会这样。
  • 我找到了发生异常的那一行。在调用 DataReader.LoadAsync 函数后,此异常被触发。我找到了stackoverflow.com/questions/16110561/…,但这个解决方案并没有解决我的问题。
猜你喜欢
  • 2016-11-09
  • 2018-05-22
  • 2017-01-12
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
  • 2016-12-27
  • 2019-04-14
  • 2017-01-18
相关资源
最近更新 更多