为什么在使用backgroundworker和progressBar并标记我获取异常和错误的进度报告?

时间:2014-06-20 21:58:58

标签: c# .net winforms

首先在form1顶部:

FileInfo[] allfiles;
string mainDirectory;

然后在form1构造函数中:

mainDirectory = @"c:\temp\screens7\";
var directory = new DirectoryInfo(mainDirectory);
allfiles = directory.GetFiles();
trackBar1.Minimum = 0;
trackBar1.Maximum = allfiles.Length;

然后按钮点击事件:

private void button1_Click(object sender, EventArgs e)
        {
            if (allfiles.Length > 1)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }

背景工作者dowork事件:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            CreateAvi.AviMovie(allfiles,backgroundWorker1);
        }

Progresschanged事件:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            label9.Invoke(new MethodInvoker(delegate { label9.Text = allfiles[e.ProgressPercentage].FullName; }));

        }

然后在另一个类中,我在一个方法中有这个循环:

public static void AviMovie(FileInfo[] FileNames,BackgroundWorker bgw1)
        {
            try
            {
                Bitmap bitmap = (Bitmap)Image.FromFile(FileNames[0].FullName);
                AviManager aviManager =
                    new AviManager(@"c:\temp\new.avi", false);
                VideoStream aviStream =
                    aviManager.AddVideoStream(false, 25, bitmap);
                int count = 0;
                for (int n = 0; n < FileNames.Length; n++)
                {
                    if (FileNames[n].Length > 0)
                    {
                        bitmap =
                           (Bitmap)Bitmap.FromFile(FileNames[n].FullName);
                        aviStream.AddFrame(bitmap);
                        bitmap.Dispose();
                        count++;
                        int pctDone = count * 100 / FileNames.Length;
                        bgw1.ReportProgress(count);
                    }
                }
                aviManager.Close();
            }
            catch
            {
                string t = "error";
            }
        }

我做了一些改变:

  1. 在AviMovie方法的新类中,我添加了bgw1变量。报告进展如下:ReportProgress(pctDown)

  2. 在进度改变事件的form1中,它是:

    private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)     {         progressBar1.Value = e.ProgressPercentage;     }

  3. 当它是这样的时候,progressBar结束了100% 但后来我想报告并在label9上显示文件,命名新类中AviMovie方法的每个文件名。

    首先我做了:

    label9.Text = allfiles[e.ProgressPercentage].FullName;
    

    然后我添加了Invoke。

    现在的问题是它从未在167中的文件101上始终显示正确的文件。 进度条也在结束前停了一点。 所有这些问题都发生在我开始使用label9时。

    当它在几秒钟之后在文件101结束前稍微停止时它会抛出异常:

    System.Reflection.TargetInvocationException was unhandled
      HResult=-2146232828
      Message=Exception has been thrown by the target of an invocation.
      Source=mscorlib
      StackTrace:
           at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
           at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
           at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
           at System.Delegate.DynamicInvokeImpl(Object[] args)
           at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
           at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
           at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.Run(Form mainForm)
           at WindowsFormsApplication1.Program.Main() in d:\C-Sharp\ReadWriteToMemory\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 19
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: System.ArgumentOutOfRangeException
           HResult=-2146233086
           Message=Value of '101' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'.
    Parameter name: Value
           Source=System.Windows.Forms
           ParamName=Value
           StackTrace:
                at System.Windows.Forms.ProgressBar.set_Value(Int32 value)
                at WindowsFormsApplication1.Form1.backgroundWorker1_ProgressChanged(Object sender, ProgressChangedEventArgs e) in d:\C-Sharp\ReadWriteToMemory\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 292
                at System.ComponentModel.BackgroundWorker.OnProgressChanged(ProgressChangedEventArgs e)
                at System.ComponentModel.BackgroundWorker.ProgressReporter(Object arg)
           InnerException: 
    

    这很奇怪,因为在form1构造函数中我将progreaaBar1的最大值设置为allfile.Lenght 最小值为0.所以我现在在form1设计器中将progressBar1更改为mnimum 0,最大1000我将其设置为1000仅用于测试。

    当我在设计师中将它设置为最大1000时,它就像它想要的那样达到167但是最后又抛出另一个例外:

    System.Reflection.TargetInvocationException was unhandled
      HResult=-2146232828
      Message=Exception has been thrown by the target of an invocation.
      Source=mscorlib
      StackTrace:
           at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
           at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
           at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
           at System.Delegate.DynamicInvokeImpl(Object[] args)
           at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
           at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
           at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.Run(Form mainForm)
           at WindowsFormsApplication1.Program.Main() in d:\C-Sharp\ReadWriteToMemory\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 19
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: System.IndexOutOfRangeException
           HResult=-2146233080
           Message=Index was outside the bounds of the array.
           Source=System.Windows.Forms
           StackTrace:
                at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
                at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
                at System.Windows.Forms.Control.Invoke(Delegate method)
                at WindowsFormsApplication1.Form1.backgroundWorker1_ProgressChanged(Object sender, ProgressChangedEventArgs e) in d:\C-Sharp\ReadWriteToMemory\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 293
                at System.ComponentModel.BackgroundWorker.OnProgressChanged(ProgressChangedEventArgs e)
                at System.ComponentModel.BackgroundWorker.ProgressReporter(Object arg)
           InnerException: 
    

    这是form1中的第292行:

    progressBar1.Value = e.ProgressPercentage;
    

    这是form1中的第293行:

    label9.Invoke(new MethodInvoker(delegate { label9.Text = allfiles[e.ProgressPercentage].FullName; }));
    

    为什么我需要在设计器中将progressBar1最大值更改为1000,如果我将其更改为allfiles.Lenght已经在构造函数中?否则它将在文件101处停止并使用mininmum和maximum来抛出异常。

    第二个例外是什么?我怎样才能修复所有这些label9文件名称报告? 在新类中的AviMovie方法中,我尝试了这一行:

    bgw1.ReportProgress(count);
    

    要报告计数,然后报告变量n,然后报告pctDone。 在所有情况下,它只是直到文件101并抛出异常。

    **它有点长,但它的所有连接试图更清楚地解释它。

1 个答案:

答案 0 :(得分:0)

您正在使用某种百分比索引FileInfo。您必须反转此计算才能获得正确索引数组的计数。