首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么我的异步方法不等待"serialPort = await SerialDevice.FromIdAsync()"?

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

Stack Overflow用户
提问于 2017-01-16 02:27:13
回答 1查看 818关注 0票数 1

我正在尝试创建一个类,用于初始化覆盆子和arduino之间的串行连接。该类还应能够通过已建立的串行连接进行读写。

我使用的代码来自microsoft developers website

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

我给Package.appxmanifest添加了串行通信功能。

<Capabilities>
  <DeviceCapability Name="serialcommunication">
    <Device Id="any">
      <Function Type="name:serialPort" />
    </Device>
  </DeviceCapability>
</Capabilities>

到目前为止,一切都很正常。Raspberry成功地从另一端的Arduino发送和接收消息。

现在,我尝试分别执行这些步骤。首先初始化串行连接,以便在应用程序需要时随时使用读写函数。

MainPage

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初始化。所以他们永远不会被分配到。

有人能给我解释一下为什么它不等待串行连接吗?那该怎么做呢?

EN

回答 1

Stack Overflow用户

发布于 2017-01-16 02:57:25

这是你的构造函数:

public SerialController()
{
    InitSerial();
}

它调用InitSerial()方法,该方法中有几个await。构造函数会立即返回,而不会执行所需的所有操作。然后调用以下方法:

serial.Write();
serial.Read();

但是这些方法依赖于在InitSerial方法中执行的每一行代码,但显然它们没有。

解决这个问题的一种方法是使InitSerial不是私有的(内部的或公共的),并让它返回Task。当你调用它的时候,你需要等待它,这样它才能被执行到完成。然后,您可以调用serial.Write()Serial.Read()

您应该避免使用async void。它们仅用于事件处理。对于其他方法,返回TaskTask<T>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41664697

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档