【问题标题】:Workflow of RFComm communication in windows store appsWindows 商店应用程序中 RFComm 通信的工作流程
【发布时间】:2014-05-18 18:03:00
【问题描述】:

我一直在努力使这项工作没有成功。

我有一个第三方设备,它将由我的 Windows 应用商店应用程序通过蓝牙控制。问题在于通信方法的异步等待性质。

当某个页面加载时,应用程序将首先启动连接。它将使用此代码启动连接:

 public async Task Test() 
    {
        var loadedDevices = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));

        var foundDevice = loadedDevices.FirstOrDefault(x => x.Name == "DEVICE_NAME");

        if (foundDevice != null) 
        {

            var connection = getConnection(foundDevice);
        }

    }

    public async Task<RfcommDeviceService> getConnection(DeviceInformation device) 
    {
        return await RfcommDeviceService.FromIdAsync(device.Id);
    }

我确实将它与我的应用程序分开,因为它无法正常工作。

获取连接后,我需要从连接流中获取 DataWriter 和 DataReader。

蓝牙设备有一个协议,我们可以写一些东西然后读取响应。但它的机制也是异步方法。 要写一个命令,我使用的是这种方法:

 private void SendCommand(string command)
    {
        Task.Run(async () => { await this.writer.FlushAsync(); }).Wait();
        this.writer.WriteString(command);
        Task.Run(async () => { await this.writer.StoreAsync(); }).Wait();
    }

然后像这样读取我在一段时间内读取的数据:

 while (!data.EndsWith("\n"))
        {
            uint messageLength = this.reader.UnconsumedBufferLength;
            uint nbytes = 0;

            Task.Run(async () => { nbytes = await this.reader.LoadAsync(1024); }).Wait();

            if (nbytes == 0)
            {
                iterates++;
                continue;
            }

            if (iterates > 3)
            {
                break;
            }

            iterates = 0;
            data += this.reader.ReadString(this.reader.UnconsumedBufferLength);
        }

问题是,有时,我不知道为什么连接有效,有时却不行。 有时它会跳过连接或 write 或 read 方法,只是忽略调用并在所有地方返回 null。

对于使用 RFComm 设备使用 async/await 的最佳实践有什么帮助吗?

我已经阅读了很多东西,这里和那里的问题,但似乎我缺乏基础(我在 MSDN 上阅读)或解释。

非常感谢任何帮助!

谢谢

【问题讨论】:

    标签: c# bluetooth windows-store-apps async-await rfcomm


    【解决方案1】:

    当你await一个异步操作已经在后台线程上执行时,你不需要添加Task.Run。所以下面的代码:

    Task.Run(async () => { nbytes = await this.reader.LoadAsync(1024); }).Wait();
    

    可以写成:

    nbytes = await this.reader.LoadAsync(1024);
    

    您也不需要调用Wait,因为这是一个阻塞操作,并且会阻塞当前线程,直到操作完成。另一个例子是方法SendCommand

    private void SendCommand(string command)
    {
        await this.writer.FlushAsync();
        this.writer.WriteString(command);
        await this.writer.StoreAsync();
    }
    

    SendCommand 中的方法将按顺序执行,因为await 有效地“暂停”该方法,直到操作完成。我认为您需要更多地了解async/await。这个article 可能会有所帮助。

    【讨论】:

    • 嗨,内德,感谢您的回答。我想阅读您要发布的资源,但我认为您忘记了 [文章][1] 上的链接。请把那个发过来好吗?
    • 没关系,谢谢。我会再读一遍(已经读过),但我可能会遗漏一些东西。谢谢!
    • 好吧,我认为这篇文章现在回答了我的问题,我可能有更多实际问题,但我会将它们发布到新线程上。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 2012-09-02
    • 2017-08-04
    相关资源
    最近更新 更多