我正在尝试基于this示例实现串行读取器。
我尝试实现main函数以从串行读取并在主页的文本框中打印它。我必须读取带有24个字符和两个结尾行“ \ r \ n”的条形码,因此我将ReadBufferLength变量初始化为26(我不知道它是否正确)。连接的参数正确并且已建立连接。我想连续运行“监听”功能,以便在使用应用程序的任何时候都能接收数据,并始终打印文本框中接收到的数据。
我对mainpage.xaml.cs的代码是:
namespace App1
{
public sealed partial class MainPage : Page
{
private CancellationTokenSource ReadCancellationTokenSource;
private SerialDevice serialPort = null;
DataReader dataReaderObject = null;
public MainPage()
{
this.InitializeComponent();
}
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
string qFilter = SerialDevice.GetDeviceSelector("COM3");
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(qFilter);
if (devices.Any())
{
string deviceId = devices.First().Id;
await OpenPort(deviceId);
}
ReadCancellationTokenSource = new CancellationTokenSource();
while (true)
{
await Listen();
}
}
private async Task OpenPort(string deviceId)
{
serialPort = await SerialDevice.FromIdAsync(deviceId);
if (serialPort != null)
{
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.BaudRate = 9600;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
txtStatus.Text = "Serial port configured successfully";
}
}
private async Task Listen()
{
try
{
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
catch (Exception ex)
{
txtStatus.Text = ex.Message;
}
finally
{
if (dataReaderObject != null)
{
dataReaderObject.DetachStream();
dataReaderObject = null;
}
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 26;
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
string strFromPort = dataReaderObject.ReadString(bytesRead);
txtPortData.Text = strFromPort;
txtStatus.Text = "Read at " + DateTime.Now.ToString(System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat.LongTimePattern);
}
}
private void CancelReadTask()
{
if (ReadCancellationTokenSource != null)
{
if (!ReadCancellationTokenSource.IsCancellationRequested)
{
ReadCancellationTokenSource.Cancel();
}
}
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
CancelReadTask();
if (serialPort != null)
{
serialPort.Dispose();
}
serialPort = null;
}
}
}
当我运行该应用程序时,Listen函数仅被调用一次,如果我在串行端口上发送某些内容,我将永远不会收到数据。可能我错过了代码中的某些内容。
答案 0 :(得分:1)
最后,我找到了解决方法...
我将System.IO.Ports包与两个不同的处理程序和一个对象收集器一起使用:
这进入SerialDevice类:
private static ObservableCollection<string> ReadValues = null;
public static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadLine();
ReadValues.Add(indata);
}
在主页中,我将这一行添加到page_loaded函数中:
mySerialDevice.GetList().CollectionChanged += NewFunctionHandler;
其中,GetList()是一个返回ReadValues变量的函数。而NewFunctionHandler类似于:
public async void NewFunctionHandler(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
// do stuff
}
}
希望这对其他人有帮助...