当前位置:  开发笔记 > 编程语言 > 正文

为什么我的异步方法不等待"serialPort = await SerialDevice.FromIdAsync()"?

如何解决《为什么我的异步方法不等待"serialPort=awaitSerialDevice.FromIdAsync()"?》经验,为你挑选了1个好方法。

我正在尝试创建一个初始化树莓和arduino之间串行连接的类.该类还应该能够通过已建立的串行连接进行读写.

我使用的代码来自微软开发者网站.

using Windows.Storage.Streams;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;

public async void Serial()
{
    /* Find the selector string for the serial device   */
    string aqs = SerialDevice.GetDeviceSelector("UART0");
    /* Find the serial device with our selector string  */
    var dis = await DeviceInformation.FindAllAsync(aqs);
    /* Create an serial device with our selected device */
    SerialDevice SerialPort = await SerialDevice.FromIdAsync(dis[0].Id);
    /* Configure serial settings */
    SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
    SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
    SerialPort.BaudRate = 9600;
    SerialPort.Parity = SerialParity.None;
    SerialPort.StopBits = SerialStopBitCount.One;
    SerialPort.DataBits = 8;

    /* Write a string out over serial */
    string txBuffer = "Hello Serial";
    DataWriter dataWriter = new DataWriter();
    dataWriter.WriteString(txBuffer);
    uint bytesWritten = await SerialPort.OutputStream.WriteAsync(dataWriter.DetachBuffer());

    /* Read data in from the serial port */
    const uint maxReadLength = 1024;
    DataReader dataReader = new DataReader(SerialPort.InputStream);
    uint bytesToRead = await dataReader.LoadAsync(maxReadLength);
    string rxBuffer = dataReader.ReadString(bytesToRead);
}

我将serialcommunication功能添加到Package.appxmanifest.


  
    
      
    
  

到目前为止一切正常.Raspberry在另一端成功地发送和接收来自Arduino的消息.

现在我尝试单独执行这些步骤.首先初始化串行连接,因此只要应用程序需要,就可以使用读写函数.

主页

namespace SerialUART
{
    public sealed partial class MainPage : Page
    {
        private SerialController serial = new SerialController();

        public MainPage()
        {
            this.InitializeComponent();
            serial.Write();
            serial.Read();
        }
    }
}

SerialController

using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using Windows.Storage.Streams;

namespace SerialUART
{
    class SerialController
    {
        private SerialDevice SerialPort;
        private DataWriter dataWriter;
        private DataReader dataReader;

        public SerialController()
        {
            InitSerial();
        }

        private async void InitSerial()
        {
            string aqs = SerialDevice.GetDeviceSelector("UART0");
            var dis = await DeviceInformation.FindAllAsync(aqs);
            SerialPort = await SerialDevice.FromIdAsync(dis[0].Id);    
            // The program does not wait here and executes Write()
            // after Write() the following code will be executed
            SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
            SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
            SerialPort.BaudRate = 9600;
            SerialPort.Parity = SerialParity.None;
            SerialPort.StopBits = SerialStopBitCount.One;
            SerialPort.DataBits = 8;
            dataWriter = new DataWriter();
            dataReader = new DataReader(SerialPort.InputStream);
        }

        public async void Read()
        {
            /* Read data in from the serial port */
            const uint maxReadLength = 1024;
            uint bytesToRead = await dataReader.LoadAsync(maxReadLength);
            string rxBuffer = dataReader.ReadString(bytesToRead);
            Debug.WriteLine(rxBuffer);
        }

        public async void Write()
        {
            /* Write a string out over serial */
            string txBuffer = "Hello Serial";
            dataWriter.WriteString(txBuffer);
            uint bytesWritten = await SerialPort.OutputStream.WriteAsync(dataWriter.DetachBuffer());
       }
    }
}

此代码不会等待serialPort,dataWriter和dataReader初始化.所以他们永远不会被分配到.

任何人都可以向我解释为什么它不等待串行连接?它应该如何完成?

所有帮助表示赞赏.提前致谢!



1> Jon Skeet..:

所有async方法都返回void- 这意味着它们开始执行,并且调用代码没有简单的方法等待,直到它实际完成后再继续.一旦你await在尚未完成的事情上使用表达式,async方法将返回调用者,已经安排了一个将在awaitable完成时执行的延续.在你的情况下,你只是继续下一个声明.

相反,您应该返回Task异步方法,并在继续之前更改调用方法以等待异步方法完成.这很难做得很优雅,因为在每种情况下你都是从构造函数调用异步方法,它们本身不能是异步的.您可能需要考虑使用异步静态方法而不是在构造函数中执行工作,构造函数可以调用异步方法,等待它们,然后调用不执行任何实际工作的实际构造函数.

在你进行任何详细的更改之前,你应该真正阅读更多关于什么asyncawait做什么 - 尝试使用它们而不理解它们是进一步问题的一个方法.

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有