我正在尝试创建一个初始化树莓和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初始化.所以他们永远不会被分配到.
任何人都可以向我解释为什么它不等待串行连接?它应该如何完成?
所有帮助表示赞赏.提前致谢!
所有async
方法都返回void
- 这意味着它们开始执行,并且调用代码没有简单的方法等待,直到它实际完成后再继续.一旦你await
在尚未完成的事情上使用表达式,async方法将返回调用者,已经安排了一个将在awaitable完成时执行的延续.在你的情况下,你只是继续下一个声明.
相反,您应该返回Task
异步方法,并在继续之前更改调用方法以等待异步方法完成.这很难做得很优雅,因为在每种情况下你都是从构造函数调用异步方法,它们本身不能是异步的.您可能需要考虑使用异步静态方法而不是在构造函数中执行工作,构造函数可以调用异步方法,等待它们,然后调用不执行任何实际工作的实际构造函数.
在你进行任何详细的更改之前,你应该真正阅读更多关于什么async
和await
做什么 - 尝试使用它们而不理解它们是进一步问题的一个方法.