【问题标题】:C#, Updating a Progress Bar Using Background Worker From a Different ClassC#,使用来自不同类的后台工作人员更新进度条
【发布时间】:2011-11-02 08:16:08
【问题描述】:

我正在尝试更新主窗体上的进度条,而工作是在不同的班级中完成的。例如:

private void transfer_Click(object sender, EventArgs e)
{
    Guid aspnetUserId = Guid.Parse(System.Configuration.ConfigurationSettings.AppSettings["ASPNetUserID"]);
    WC1toWC2Transfer transfer = new WC1toWC2Transfer(aspnetUserId);

    backgroundWorker1.RunWorkerAsync(transfer);  
}

然后在后台方法实际调用方法:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    WC1toWC2Transfer transfer = e.Argument as WC1toWC2Transfer;
    transfer.WC1ToWC2EmployerTransfer(log, wc1ConnStr, wc2ConnStr, progressBar1);
}

在 WC1ToWC2EmployerTransfer 方法中,我将进度条设置为最大值,并在每次使用此方法将某些内容传输到数据库时更新值,但是当我这样做时,什么也没有发生。方法中有代码在数据库中运行存储过程,但是一旦遇到该部分代码,它就会停止调试,我必须再次运行该过程。

我在这里做错了吗?我是否需要重写我所拥有的,以便实际的方法在主要形式中,而不是在不同的类中?我是一名初级开发人员(几个月前才开始),如果我做的事情明显错误或者我解释得不够清楚,请原谅我。

任何帮助将不胜感激。

【问题讨论】:

  • 不确定这是怎么回事,但您肯定想解决“它停止调试”的问题。 BackgroundWorker 吞下异常并将它们传递给具有 e.Error 属性的 RunworkerCompleted 事件处理程序。你不想忽略的东西。不忽略它的最佳方法是使用 Debug + Exceptions,勾选 Thrown 复选框以获得 CLR 异常。

标签: c# backgroundworker


【解决方案1】:

除非您在主线程上,否则您无法更改 UI,而 BackgroundWorker 不会。

您需要做的是在主窗体中创建一个事件处理程序来处理后台工作者的 ProgressChanged 事件。

例如

// this method should be in your main form.
private void backgroundworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // update your progress bar here.
}

在后台工作人员中,您调用ReportProgress 方法,该方法将触发 ProgressChanged 事件。

有一个很好的例子here

【讨论】:

    【解决方案2】:

    我认为原因是您获得了IllegalCrossThreadException,因为您试图从与创建控件不同的线程访问控件。 BackgroundWorker 提供了一个 ReportProgress 方法和一个 ProgressChanged 事件,通常用于此类更新,并将在 UI 线程上执行。当从另一个线程而不是 UI 线程访问进度条时,这样做:

    if(progressBar1.InvokeRequired) {
      progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Maximum = someValue; }));
    }
    

    作为旁注:将进度条传递给您的工人阶级并不是很好的设计。表单可能会关闭,它可能会被丢弃,而工作人员对此一无所知,最终以可能未被捕获的ObjectDisposedException 失败。此外,当它可能不需要时,您正在使工作人员依赖System.Windows.Forms。而是让您的工作人员通过事件报告进度,并将其从创建工作人员的类传递到您的进度条。

    【讨论】:

    • 另外,如果您有兴趣,Progression(免责声明:我写的)是一个非常简单的进度计算库,它允许您的工作方法正确报告进度,而无需了解有关 UI 的任何信息. UI 订阅线程安全事件,或者BackgroundWorker 可以订阅和报告事件。
    猜你喜欢
    • 2017-01-21
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    相关资源
    最近更新 更多