简体   繁体   English

实施backgroundworker以另一种形式显示进度条

[英]Implementing backgroundworker to display progress bar in another form

My main form is performing long operations.In order to tell the user that the application is processing and not freezing I wanted to implement a progress bar in another form. 我的主要形式是执行较长的操作。为了告诉用户应用程序正在处理而不是冻结,我想以另一种形式实现进度条。

It seems that you can't interact with controls if you're not on the main thread. 如果您不在主线程上,则似乎无法与控件进行交互。 I tried to implement backgroundworker as suggested in the link below but without success. 我尝试按照以下链接中的建议实施backgroundworker,但未成功。

http://perschluter.com/show-progress-dialog-during-long-process-c-sharp/ http://perschluter.com/show-progress-dialog-during-long-process-c-sharp/

Same thing with Task-based Asynchronous Pattern 与基于任务的异步模式相同

How to update the GUI from another thread in C#? 如何从C#中的另一个线程更新GUI?

The closer to success I've been is with encapsulating the call of the progress bar form in another thread : 我最接近成功的地方是将进度条窗体的调用封装在另一个线程中:

Form_Process f_p = new Form_Process();
Thread newWindowThread = new Thread(new ThreadStart(() =>
{
    // Create and show the Window

    f_p.ShowDialog();
    // Start the Dispatcher Processing
    System.Windows.Threading.Dispatcher.Run();
}));

// Set the apartment state
newWindowThread.SetApartmentState(ApartmentState.STA);
// Make the thread a background thread
newWindowThread.IsBackground = true;
// Start the thread
newWindowThread.Start();

f_p.label_Progression.Text = "Call to exe";
f_p.progressBar1.Value = 30;
f_p.Refresh();

But when I call a function in the main thread and I try to update the progress bar, the cross-thread exception is logically lifted. 但是,当我在主线程中调用函数并尝试更新进度条时,逻辑上会取消跨线程异常。

Am I missing something ? 我想念什么吗?

You can't set control properties on a form from a different thread. 您不能在其他线程的表单上设置控件属性。 You need an invokation to do this. 您需要发票才能执行此操作。

On your form, create a function: 在表单上,​​创建一个函数:

public void SetProgressText(string value) {
     if (this.InvokeRequired) {
         Action<string> progressDelegate = this.SetProgressText;
         progressDelegate.Invoke(value);
     } else {
         label_Progression.Text = value;
     }
}

And then, instead of 然后,代替

f_p.label_Progression.Text = "Call to exe";

call 呼叫

f_p.SetProgressText("Call to exe");

Same for the progress bar. 进度条也一样。 You can put all invokations inside one function though. 您可以将所有调用放在一个函数中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM