C# 后台工作人员部分或全部更新进度条,然后将其删除

C# 后台工作人员部分或全部更新进度条,然后将其删除,c#,winforms,multithreading,progress-bar,backgroundworker,C#,Winforms,Multithreading,Progress Bar,Backgroundworker,不久前,我要求提供一些关于设置进度条的帮助,以向用户显示给定文件和文件夹集的进度 请看这里: 因此,我设法让它工作,但在某些情况下,它部分填补,有时根本没有。正在退出,但出现以下异常 TargetInvocationException未处理。。调用的目标已引发异常 在我的程序中轰炸到这行代码 [MTAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTex

不久前,我要求提供一些关于设置进度条的帮助,以向用户显示给定文件和文件夹集的进度

请看这里:

因此,我设法让它工作,但在某些情况下,它部分填补,有时根本没有。正在退出,但出现以下异常


TargetInvocationException未处理。。调用的目标已引发异常

在我的程序中轰炸到这行代码

[MTAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm()); <-- Exception raised at this line !!!
}
多亏了一个叫“塞西尔有名字”的家伙


应该是这样。期待得到一些关于我这个小问题的回复。

尽管您不需要在ProgressChanged事件处理程序中使用BeginInvoke,但您上面发布的代码看起来不错。它看起来像Application.Run引发异常的原因是调用堆栈中没有任何其他try/catch

您列出的异常不是正在发生的实际问题,而是一个包装器。如果您查看抛出异常的InnerException,它应该会为您提供更多关于发生了什么的信息

如果您需要更多帮助,您可能应该发布内部异常的详细信息,我们可以提供更多帮助


根据内部异常,您正在设置的进度条值似乎不在进度条的最小值和最大值之间。您是否设置了最小值和最大值,并验证了设置在进度条中的所有值都在它们之间?

尽管您不需要在ProgressChanged事件处理程序中使用BeginInvoke,但上面发布的代码看起来不错。它看起来像Application.Run引发异常的原因是调用堆栈中没有任何其他try/catch

您列出的异常不是正在发生的实际问题,而是一个包装器。如果您查看抛出异常的InnerException,它应该会为您提供更多关于发生了什么的信息

如果您需要更多帮助,您可能应该发布内部异常的详细信息,我们可以提供更多帮助


根据内部异常,您正在设置的进度条值似乎不在进度条的最小值和最大值之间。是否设置了最小值和最大值,并验证了在进度栏中设置的所有值都在它们之间?

在Visual Studio的“调试”菜单下,单击“异常…”。。。。选中公共语言运行时异常复选框并运行代码。这样,当抛出异常时,进程将中断并以绿色突出显示该行


还建议您使用try-catch块尝试从错误中恢复,或至少记录错误。

在Visual Studio中的“调试”菜单下,单击“异常…”。。。。选中公共语言运行时异常复选框并运行代码。这样,当抛出异常时,进程将中断并以绿色突出显示该行


还建议您使用try-catch块尝试从错误中恢复,或至少记录错误。

首先,您实际上可以使用已经使用的ProgressChanged事件以线程安全的方式更新该状态标签;BackgroundWorker.ReportProgress有一个重载,它接受一个对象参数来传递用于此目的的附加信息

其次,如果问题是您试图将进度条的值设置为超出最大值,则可能是您的硬编码值100与进度条的最大值属性不对应,尽管这似乎不太可能,因为我认为100是默认值

因此,我建议对您的代码进行以下更改:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < allFiles.Length; i++)
    {
        localSize += allFiles[i].Length;
        localFiles++;

        // this you can pass to ReportProgress
        string statusText = allFiles[i].Name;

        int progressPercentage = (100 * i) / allFiles.Length;
        worker.ReportProgress(progressPercentage, statusText);
    }
}

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // now that this is being done here, it is thread-safe
    string statusText = e.UserState as string;
    if (!string.IsNullOrEmpty(statusText))
    {
        toolStripStatusLabel.Text = statusText;
    }

    // your progress should be capped at the ProgressBar's Maximum,
    // rather than 100
    int progress = e.ProgressPercentage;
    int maxProgress = fileRetrievalProgressBar.Maximum;
    fileRetrievalProgressBar.Value = Math.Min(progress, maxProgress);
}

首先,您实际上可以使用已经使用的ProgressChanged事件以线程安全的方式更新状态标签;BackgroundWorker.ReportProgress有一个重载,它接受一个对象参数来传递用于此目的的附加信息

其次,如果问题是您试图将进度条的值设置为超出最大值,则可能是您的硬编码值100与进度条的最大值属性不对应,尽管这似乎不太可能,因为我认为100是默认值

因此,我建议对您的代码进行以下更改:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < allFiles.Length; i++)
    {
        localSize += allFiles[i].Length;
        localFiles++;

        // this you can pass to ReportProgress
        string statusText = allFiles[i].Name;

        int progressPercentage = (100 * i) / allFiles.Length;
        worker.ReportProgress(progressPercentage, statusText);
    }
}

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // now that this is being done here, it is thread-safe
    string statusText = e.UserState as string;
    if (!string.IsNullOrEmpty(statusText))
    {
        toolStripStatusLabel.Text = statusText;
    }

    // your progress should be capped at the ProgressBar's Maximum,
    // rather than 100
    int progress = e.ProgressPercentage;
    int maxProgress = fileRetrievalProgressBar.Maximum;
    fileRetrievalProgressBar.Value = Math.Min(progress, maxProgress);
}

TargetInvocationException未处理。。调用的目标已引发异常-InnerException是什么?这将为您提供一条关于实际出错原因的线索。因为我相信它应该由[MTAThread]引导-不,Windows窗体主方法应始终标记为[STAThread]。TargetInvocationException只是真正异常的包装器异常。在exception helper对话框中发布异常视图详细信息的完整堆栈跟踪,然后复制StackTrace属性y itowlson。。。我将更改main方法上的属性。我在找那个

整个堆栈跟踪,我从来没有看到它。。。好的旧java日子和“cmd”。。。整个堆叠的痕迹就在你眼前。如果可以的话,我现在就发布一个堆栈跟踪。我认为进度条的使用方式没有设置其最大值或最小值。TargetInvocationException未处理。。调用的目标已引发异常-InnerException是什么?这将为您提供一条关于实际出错原因的线索。因为我相信它应该由[MTAThread]引导-不,Windows窗体主方法应始终标记为[STAThread]。TargetInvocationException只是真正异常的包装器异常。在exception helper对话框中发布异常视图详细信息的完整堆栈跟踪,然后复制StackTrace属性y itowlson。。。我将更改main方法上的属性。我在寻找完整的堆栈跟踪,我从来没有看到它。。。好的旧java日子和“cmd”。。。整个堆叠的痕迹就在你眼前。如果可以的话,我现在就发布一个堆栈跟踪。我认为进度条的使用方式没有设置它的最大值或最小值。如果你是说“用户未处理”,那么是的,这已经被检查过了。抛出列没有被选中。很抱歉,我的意思是不是抛出列。如果你的意思是“用户未处理”,那么是的,这已经被选中了。投掷栏没有被选中。很抱歉遗漏了,我的意思是不是投掷栏。我已经在上面的链接中发布了这个例外。问题与生成值的方式有关,它们被近似为100%,然后作为值应用。也许需要一种简单的文字方法。生成填充条所需的值并将该值应用到条上的更简单方法。我想我知道如何解决这个问题……我已经在上面的链接中发布了这个例外。问题与生成值的方式有关,它们被近似为100%,然后作为值应用。也许需要一种简单的文字方法。生成填充条所需的值并将该值应用到条上的更简单方法。我想我知道如何解决这个问题……BackgroundWorker的逻辑中已经有了try/catch,没有必要再添加一个。您可以在RunWorkerCompleted中检索异常(如果有)。@LIGGET78:我没有意识到!谢谢你指出这一点。这正是我一直在想的。。。谢谢你,丹。我要试一试,看看我能得到什么。我认为这一点,以及这里和那里的一些调整应该“应该做到”。谢谢你指出这一点。BackgroundWorker的逻辑中已经有try/catch,没有必要再添加一个。您可以在RunWorkerCompleted中检索异常(如果有)。@LIGGET78:我没有意识到!谢谢你指出这一点。这正是我一直在想的。。。谢谢你,丹。我要试一试,看看我能得到什么。我认为这一点,以及这里和那里的一些调整应该“应该做到”。谢谢你指出这一点。我已经意识到了这一点。
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < allFiles.Length; i++)
    {
        localSize += allFiles[i].Length;
        localFiles++;

        // this you can pass to ReportProgress
        string statusText = allFiles[i].Name;

        int progressPercentage = (100 * i) / allFiles.Length;
        worker.ReportProgress(progressPercentage, statusText);
    }
}

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // now that this is being done here, it is thread-safe
    string statusText = e.UserState as string;
    if (!string.IsNullOrEmpty(statusText))
    {
        toolStripStatusLabel.Text = statusText;
    }

    // your progress should be capped at the ProgressBar's Maximum,
    // rather than 100
    int progress = e.ProgressPercentage;
    int maxProgress = fileRetrievalProgressBar.Maximum;
    fileRetrievalProgressBar.Value = Math.Min(progress, maxProgress);
}