【问题标题】:How do I set the status bar from a static [duplicate]如何从静态 [重复] 设置状态栏
【发布时间】:2019-04-23 19:20:48
【问题描述】:
我有一个表单(称为 Form1),并创建了一个状态条(称为 toolStripProgressBar1),带有一个标签和一个进度条。我有一个函数,当您按下按钮并获取一些数据并对其进行处理时调用它,效果很好。
我想向用户提供一些关于其进度的信息,所以我想设置标签和进度条,但我无法设置它
private static async Task GetSurvey(string surid)
{
Form1.toolStripProgressBar1.Value = 10;
【问题讨论】:
标签:
c#
winforms
statusbar
【解决方案1】:
如果你不把它当作静态的,它会容易得多;在可以访问表单实例变量的方法中完成这项工作将使这变得非常简单。请注意,尽管您的进度条(== 应该)由窗口线程更新,并且按钮单击事件处理程序等大多数事情都是由同一线程操作的。这意味着您单击按钮,创建进度条的线程开始忙于执行您长时间运行的代码......
现在,您正在异步运行任务,这很好,只需确保等待任何冗长的操作,以便窗口线程可以在此时切换到后台进程并返回其主要工作(更新 UI)否则您将不会看到进度条非常有效地更新。不要尝试将表单控件从在不同线程上运行的代码更新到主窗口线程。
如果你不清楚 async/await 是如何工作的,想象一下在某个方法块中遇到await 时,正在执行代码的线程将创建一个后台进程来完成等待部分,它本身会回到调用堆栈,直到它到达第一个未标记为异步的方法,然后从那里继续。实际上,在 Windows 窗体应用程序中,您希望所有响应按钮单击“做事”的代码都被标记为异步,这样您就可以将窗口线程完全从代码上下文中释放出来,然后重新开始保持UI 响应,无论何时使用 await
执行此操作的另一种方法可能是调整 BackgroundWorker - 您附加一个 DoWork 事件处理程序来完成这项工作,并且作为此代码的一部分,它应该定期调用 ReportProgress 方法,传入一个 int 百分比完成。 BGWorker 上的 ProgressChanged 事件处理程序用于设置百分比条/Uu 元素 - 关键是您需要知道 DoWork 在不是窗口线程的线程上运行(并且不得从线程以外的线程访问窗口控件创建它们的,通常是窗口线程),所以我们不直接从 DoWork 访问进度条,而是调用 ReportProgress 并导致 ProgressChanged 事件触发,并且 BGWorker 故意安排事情,以便该事件处理程序中的代码运行在窗口线程上(实际上是创建工作者的线程,但这应该是相同的)