messageBox.Show() 做什么以停止执行 UI 线程?
What does messageBox.Show() do in order to stop the execution of a UI thread?
在 WPF 应用程序中,我将消息输出到文本框,在这些消息之间我调用了一个函数来设置仪器。但是,所有消息都同时出现(在函数调用结束时)。
我真的不知道如何清楚地解释我的问题。我会尽力...
我有一个 WPF 应用程序,它使用串行端口从仪器中获取数据。该应用程序包含一些按钮和一个用于输出消息的文本框。按下按钮后,应用程序会向仪器发送命令以更改某些参数(通过函数 Set_COMM_MODE()
)和 returns。更改大约需要 5-10 秒。因此我所做的是:我在调用之前输出了一条 "Please Wait" 消息,在调用 return 之后输出了一条 "Done" 消息。
代码中的OuputText()
函数只调用了TextBox.AppendText()
方法。
我的问题:调用 return 时,所有输出文本都在文本框中乱七八糟。我预计会收到 Please Wait... 然后 5-10 秒后收到 "Done" 消息。但它是同时出现的。但是,当我在第一条消息之后(函数调用之前)放置 MessageBox
时,该消息出现在文本框输出中(w/o 被调用的函数)。但是问题是我必须在 MessageBox
上按 OK 才能继续。
Q(1):我怎样才能让后者发生 w/o 不得不求助于 MessageBox
Q(2): MessageBox
做了什么来产生这种行为?
我试过:使用 Dispatch.Invoke()
方法在另一个线程上 运行 OutputText
。
这个()和我遇到的问题类似,但是好像没有得到确定的答案,我也没有很好地理解解决方案。
void StartTest_btn_Click(object sender, RoutedEventArgs e)
{
OutputText("Please Wwait\r\n"); //<---- 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("Done\r\n"); //<--- This should appear 5-10s later
}
我希望立即显示 "Please wait",然后在 5-10 秒后显示 "Done" 消息显示,在函数 Set_COMM_MODE()
.
的 return 之后
正如我在评论中所写,您真的应该只将(主)UI 线程用于 UI。
在工作线程上执行任何其他长 运行 非 UI 操作。
你可能不介意 "hang" UI 10 秒,但用户肯定会生气。此外,阻止 UI 线程会导致 Windows 认为您的应用已冻结,因此您将获得漂亮的 "not responding" 徽章和所有相关内容。这不仅看起来很糟糕,而且会导致各种副作用。
您真的应该环顾四周,看看 .NET 为您提供了哪些解决这类问题的方法。
看,这是你的工作流程:
- 打印消息
- 开始初始化
- ???
- 初始化完成-->打印"done"
- 开始运行
这是什么?这是一个异步处理。您启动一个操作并异步继续 - 也就是说,仅当操作完成时。
.NET 为您提供了很多工具,例如APM(异步编程模型)。但实现异步处理的最巧妙和最强大的方法是 TAP - 基于任务的异步编程模式,更广为人知的名称是 async
/await
.
你看,使用 TAP 只需几行代码就可以解决你的问题:
async void StartTest_btn_Click(object sender, RoutedEventArgs e)
{
OutputText("Please Wait\r\n");
// 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("Done\r\n");
}
您真的应该更多地了解现代编程技术,TAP 就是其中之一。
在 WPF 应用程序中,我将消息输出到文本框,在这些消息之间我调用了一个函数来设置仪器。但是,所有消息都同时出现(在函数调用结束时)。
我真的不知道如何清楚地解释我的问题。我会尽力...
我有一个 WPF 应用程序,它使用串行端口从仪器中获取数据。该应用程序包含一些按钮和一个用于输出消息的文本框。按下按钮后,应用程序会向仪器发送命令以更改某些参数(通过函数 Set_COMM_MODE()
)和 returns。更改大约需要 5-10 秒。因此我所做的是:我在调用之前输出了一条 "Please Wait" 消息,在调用 return 之后输出了一条 "Done" 消息。
代码中的OuputText()
函数只调用了TextBox.AppendText()
方法。
我的问题:调用 return 时,所有输出文本都在文本框中乱七八糟。我预计会收到 Please Wait... 然后 5-10 秒后收到 "Done" 消息。但它是同时出现的。但是,当我在第一条消息之后(函数调用之前)放置 MessageBox
时,该消息出现在文本框输出中(w/o 被调用的函数)。但是问题是我必须在 MessageBox
上按 OK 才能继续。
Q(1):我怎样才能让后者发生 w/o 不得不求助于 MessageBox
Q(2): MessageBox
做了什么来产生这种行为?
我试过:使用 Dispatch.Invoke()
方法在另一个线程上 运行 OutputText
。
这个(
void StartTest_btn_Click(object sender, RoutedEventArgs e)
{
OutputText("Please Wwait\r\n"); //<---- 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("Done\r\n"); //<--- This should appear 5-10s later
}
我希望立即显示 "Please wait",然后在 5-10 秒后显示 "Done" 消息显示,在函数 Set_COMM_MODE()
.
正如我在评论中所写,您真的应该只将(主)UI 线程用于 UI。 在工作线程上执行任何其他长 运行 非 UI 操作。
你可能不介意 "hang" UI 10 秒,但用户肯定会生气。此外,阻止 UI 线程会导致 Windows 认为您的应用已冻结,因此您将获得漂亮的 "not responding" 徽章和所有相关内容。这不仅看起来很糟糕,而且会导致各种副作用。
您真的应该环顾四周,看看 .NET 为您提供了哪些解决这类问题的方法。
看,这是你的工作流程:
- 打印消息
- 开始初始化
- ???
- 初始化完成-->打印"done"
- 开始运行
这是什么?这是一个异步处理。您启动一个操作并异步继续 - 也就是说,仅当操作完成时。
.NET 为您提供了很多工具,例如APM(异步编程模型)。但实现异步处理的最巧妙和最强大的方法是 TAP - 基于任务的异步编程模式,更广为人知的名称是 async
/await
.
你看,使用 TAP 只需几行代码就可以解决你的问题:
async void StartTest_btn_Click(object sender, RoutedEventArgs e)
{
OutputText("Please Wait\r\n");
// 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("Done\r\n");
}
您真的应该更多地了解现代编程技术,TAP 就是其中之一。