在 WPF 应用程序中,我将消息输出到文本框,在这些消息之间,我调用设置仪器的函数。但是,所有消息同时显示(在函数调用结束时(。
我真的不知道如何清楚地解释我的问题。我试试... 我有一个WPF应用程序,它使用串行端口从仪器中获取数据。该应用程序包含一些按钮和用于输出消息的文本框。按下按钮后,应用程序向仪器发送命令以更改某些参数(通过函数Set_COMM_MODE()
(,然后返回。更改大约需要 5-10 秒。因此,我所做的是:我在呼叫之前输出了"请稍候"消息,在呼叫返回后输出了"完成"消息。 代码中的OuputText()
函数仅调用TextBox.AppendText()
方法。 我的问题:所有输出文本在呼叫返回时都会在文本框中大量出现。我期待一个请稍候...然后5-10秒后收到"完成">消息。但它同时出现。但是,当我在第一条消息之后(在函数调用之前(放置一个MessageBox
时,该消息出现在文本框输出中(没有正在调用的函数(。但是问题是我必须在MessageBox
上按确定才能继续。
问(1(:我怎样才能让后者发生而不必求助于MessageBox
问(2(:MessageBox
做什么才能产生这种行为?
我试过:使用Dispatch.Invoke()
方法在另一个线程上运行OutputText
。 这个(暂停像 MessageBox.Show(( 这样的窗口(与我遇到的问题类似,但似乎没有得到明确的答案,而且我不太了解解决方案。
void StartTest_btn_Click(object sender, RoutedEventArgs e)
{
OutputText("Please Wwaitrn"); //<---- This should appear at once.
MessageBox.Show("Please Wwait"); //<--without this, both messages appear at same time after 10s.
Set_COMM_MODE("02"); //<--- This takes around 5-10s
OutputText("Donern"); //<--- This should appear 5-10s later
}
我希望在函数返回后立即显示">请稍候">,然后在 5-10 秒后显示"完成">消息Set_COMM_MODE()
。
正如我在评论中所写,您实际上应该仅将(主(UI 线程用于 UI。 在工作线程上执行任何其他长时间运行的非 UI 操作。
您可能不介意"挂起"UI 10 秒钟,但用户肯定会感到恼火。此外,阻止 UI 线程会导致 Windows 认为你的应用被冻结,所以你会得到漂亮的"无响应"徽章和所有相关的东西。这不仅看起来很糟糕,而且还会引起各种副作用。
您真的应该环顾四周,看看 .NET 为此类问题提供了什么。
看,这是您的工作流程:
- 打印消息
- 开始初始化
- ???
- 初始化完成 -->打印"完成">
- 开始运行
这是怎麽?这是一个异步处理。您启动一个操作并异步继续 - 这意味着,只有在操作完成时。
.NET为此提供了许多工具,例如APM(异步编程模型(。但是实现异步处理的最简洁,最强大的方法是TAP - 基于任务的异步编程模式,更广为人知的是async
/await
。
看,您的问题可以通过TAP的几行来解决:
async void StartTest_btn_Click(object sender, RoutedEventArgs e)
{
OutputText("Please Waitrn");
// Set_COMM_MODE will be executed on a worker thread!
// The main (UI) thread won't block. It will continue.
// But the StartTest_btn_Click method itself will pause until the task is finished.
await Task.Run(() => Set_COMM_MODE("02"));
// This line will only be executed, after the Set_COMM_MODE call is completed;
// furthermore, it will be executed on the UI thread again!
OutputText("Donern");
}
您应该真正了解有关现代编程技术的更多信息,TAP就是其中之一。