为什么我的应用程序在连接到串行端口时导航到 MainPage 两次时停止响应?

Why does my app stop responding when navigating to MainPage twice when connecting to serial port?

我正在开发一个简单的 UWP 应用程序,它需要侦听连接到附有 rfid reader 的 esp32 的串口。

它需要接收卡片的UID,导航到新页面,然后在定时器结束后导航回原始页面。或者点击按钮。

一切正常,除了我导航回原始父页面的部分。我相信这是因为该应用程序正在尝试重新连接到串行端口,但它不可用。我通过创建一个带有串行连接设置的设置按钮来测试我的理论,它确实按预期工作。

那么,Page_Loaded 是否会在每次重新加载页面时触发?是否有仅在第一次加载表单时触发的函数?我根本无法处理串口工作,我只是得到一个未处理的异常。虽然让串行端口保持打开状态我没有问题,但这似乎也会引起问题!

请看下面的一些示例代码:

private async void setupCOM()
        {
            string qFilter = SerialDevice.GetDeviceSelector("COM4"); //please note this is hard coded to COM4 - probably need to modify this at some point.
            DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(qFilter);

            if (devices.Any())
            {
                string deviceId = devices.First().Id;

                await OpenPort(deviceId);
            }

            ReadCancellationTokenSource = new CancellationTokenSource();

            while (true)
            {
                await Listen();
            }
        }

我正在尝试在 Page_Loaded 上启动 setupCOM 函数,它在第一次加载页面时有效,但在第二次导航页面时无效。

private async Task ReadAsync(CancellationToken cancellationToken)
{
    Task<UInt32> loadAsyncTask;

    uint ReadBufferLength = 64;  // only when this buffer would be full next code would be executed

    dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;

    loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);   // Create a task object

    UInt32 bytesRead = await loadAsyncTask;    // Launch the task and wait until buffer would be full

    if (bytesRead > 0)
    {
        string strFromPort = dataReaderObject.ReadString(bytesRead);
        int fstLetter = strFromPort.IndexOf("Info");
        int lstLetter = strFromPort.IndexOf("Info", fstLetter + 1);
        if ((fstLetter >= 0) && (lstLetter > 0)) strFromPort = strFromPort.Substring(fstLetter, lstLetter - fstLetter);
        Debug.WriteLine(strFromPort);
        Debug.WriteLine("Read at " + DateTime.Now.ToString(System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat.LongTimePattern));
        //txtresult.Text = strFromPort;
        //serialPort.Dispose();
        this.Frame.Navigate(typeof(user_login), strFromPort);
        //navpage();
    }
    }

以上函数读取和处理接收到的字符串,然后传递到新的 user_login 表单。

下一个表单有一个 15 秒的倒计时,时间过后表单将导航回主页。但它只是停止响应一切。我很确定这是因为它正在尝试重新连接到 com 端口。

有没有人有什么想法?

这很令人沮丧,所以如果有人能提供帮助,我将永远感激 :)

谢谢

安德鲁

So, does Page_Loaded fire every time the page is reloaded?

是的。

Is there a function which only fires on the first loading of the form?

您可以使用布尔标志来确定是否执行您的方法:

private bool _hasBeenLoaded;
private void OnLoaded(object sender, RoutedEventArgs e)
{
    if (!_hasBeenLoaded)
    {
        _hasBeenLoaded = true;

        //your code to be executed only once...
    }
}

也许您需要使用Page.NavigationCacheMode来缓存主页面,以便您可以导航回正确保存先前设置的主页面。如下:

<page NavigationCacheMode="Required" />