如何从单独类中的代码更新 UI 进度条或后台工作程序?

发布于 2024-10-02 17:07:46 字数 703 浏览 6 评论 0原文

对于 C# 来说有些陌生,但我在让这些东西正常工作方面遇到了一个主要问题,因为如果我的后台工作程序通过使用另一个类的方法来运行一个很长的进程,那么该类将无法访问后台工作程序以更新进度。

例如:

private void bgWorker_DoWork(object sender DoWorkEventArgs e)
{
    bgArgs args = e.Argument as bgArgs;
    MyClass objMyClass = new MyClass();

    MyClass.MyMethod(strValue, args.Option);

    //Do something based on return value of long process.
}

如果我尝试从类“MyClass”更新 bgWorker,它无法“看到”bgWorker,它不存在于类的上下文中,它位于 UI 类中,因为在 Visual Studio 中,这就是您将其拖动的位置从工具箱中。

我让它工作的唯一方法是将整个 UI 表单传递给该类,这在尝试从主表单以外的任何地方访问该类时会产生其他问题。从那里,我只需在循环运行时通过 ProgressBar1.PerformStep() 手动更新进度栏。

另外,我已经将进度条上的修饰符更改为内部,所以并不是说该类看不到进度条。

我也许可以通过该方法将 bgworker 本身传递给类,但这似乎不对。

Somewhat new to C# but I have a major problem with getting these things to work because if my background worker is running a long process by using a method from another class, then that class has no access to the background worker in order to update the progress.

For instance:

private void bgWorker_DoWork(object sender DoWorkEventArgs e)
{
    bgArgs args = e.Argument as bgArgs;
    MyClass objMyClass = new MyClass();

    MyClass.MyMethod(strValue, args.Option);

    //Do something based on return value of long process.
}

If I try to update bgWorker from the class "MyClass", it cannot "see" bgWorker, it doesn't exist in the context of the class, it's in the UI class because in Visual Studio, that's where you drag it from the toolbox.

The only way I've gotten it to work is to pass the whole UI form to the class, which creates other problems when trying to access that class from anywhere but the main form. From there I just update the progress bar manually via ProgressBar1.PerformStep() as it runs through the loops.

Also, I've already changed the modifier on my progress bar to internal, so it's not that the class doesn't see the progress bar.

I might be able to pass the bgworker by itself to the class through the method, but that just doesn't seem right.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冰雪梦之恋 2024-10-09 17:07:46

我认为你的架构需要在这里修改。后台工作者用于在后台运行操作,就像眼不见心不烦。当它运行时,您可以通过观察BackgroundWorker.ProgressChanged 事件来接受反馈,这将帮助您使用PerformStep() 增加进度条。但是,您不应尝试在运行时更改BackgroundWorker。这会让你陷入线程问题,我是不确定你真的想要:) 你看,BackgroundWorker 在运行时使用不同的线程来执行其操作,因此在运行时更改它意味着你必须访问它正在执行其工作的线程。这变得很难看。最好只给它一个执行方法,让它运行,检查其 ProgressChanged,然后等待它完成。

I think your architecture needs revising here. The background worker is for running operations in the background, like out-of-sight-out-of-mind. While it is running, you can accept feedback from it by observing the BackgroundWorker.ProgressChanged event, which will help you increment your progress bar with PerformStep(). However, you shouldn't attempt to alter the BackgroundWorker while it is running. This gets you into Threading issues, which I'm not sure you really want :) You see, the BackgroundWorker uses a different thread to perform its operations when it runs, so changing it while running means you have to access the thread it is performing its work upon. This gets ugly. It is best to just give it a method to execute, let it run, check in on its ProgressChanged, and wait for it to finish.

音栖息无 2024-10-09 17:07:46

假设我正确理解你的问题,你可能需要创建一个可以访问 UI 进度条的方法,尽管有源线程。当您尝试设置该值时,下面的代码将避免您破坏应用程序。

private delegate void UpdateProgressBarCallback(int barValue);
private void UpdateProgressBarHandler(int barValue)
{
    if (this.progressBar1.InvokeRequired)
        this.BeginInvoke(new UpdateProgressBarCallback(this.UpdateProgressBarHandler), new object[]{ barValue });
    else
    {
        // change your bar
        this.progressBar1.Value = barValue;
    }
}

[请参阅 http://msdn.microsoft.com/en -us/library/ms171728%28VS.80%29.aspx ]

然后你只需调用 UpdateProgressBar(value); (同样,如果您希望这一步进行,您可以调整参数/方法的操作方式)

接下来您可以通过以下几种方法来实现:您可以使后台工作人员(因为它已经在另一个类中)事件驱动,然后附加进度更改并更新 UI;或者您可以将委托传递给线程工作人员作为参考,以便它知道在哪里调整 UI。

发表评论并给我留下一个方向,我会看看是否可以帮助您(并确认我理解这个问题)。

Assuming I'm understanding your question correctly you probably need to make a method that can access the UI progressBar despite the source thread. The below will do just that saving you from blowing up the application when you try to set the value.

private delegate void UpdateProgressBarCallback(int barValue);
private void UpdateProgressBarHandler(int barValue)
{
    if (this.progressBar1.InvokeRequired)
        this.BeginInvoke(new UpdateProgressBarCallback(this.UpdateProgressBarHandler), new object[]{ barValue });
    else
    {
        // change your bar
        this.progressBar1.Value = barValue;
    }
}

[see http://msdn.microsoft.com/en-us/library/ms171728%28VS.80%29.aspx ]

Then you just call UpdateProgressBar(value); (likewise, if you want this to step you can adjust the arguments/way the method operates)

Next you can go about this a few ways: You can make your background worker (since it's already in another class) event driven and then attach progress changes and update the UI; or you can pass a delegate to the thread workers as a reference so it knows where to adjust the UI.

Comment and leave me a direction to go and I'll see if I can help you (and confirm I understand the question).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文