从BackgroundWorker调用的未处理的ObjectDisposedException

时间:2012-08-29 04:45:58

标签: c# multithreading backgroundworker objectdisposedexception

如果我在VisualStudio 2010中不使用调试,我的应用程序按预期工作,但我在调试模式下收到ObjectDisposedException投诉。我已阅读MS文档和其他几个主题,我无法发现问题。代码中记录了异常点,随后是堆栈跟踪。谢谢你的帮助。

        Form1.cs

        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Data;
        using System.Drawing;
        using System.Linq;
        using System.Text;
        using System.Windows.Forms;
        using System.Threading;
        using CSharpJExcel.Jxl;

        namespace Importer
        {
            public partial class Form1 : Form
            {
                public Form1()
                {
                    InitializeComponent();
                    openFileDialog1.Filter = "Text Files (.xls)|*.xls|All Files (*.*)|*.*";
                    openFileDialog1.FilterIndex = 1;
                    openFileDialog1.FileName = as400TextBox.Text;
                }

                delegate void messageBoxCallback(string text);

                private void button1_Click(object sender, EventArgs e)
                {
                    openFileDialog1.FileName = as400TextBox.Text;
                    if (openFileDialog1.ShowDialog() == DialogResult.OK)
                    {
                        as400File = openFileDialog1.FileName;
                        as400TextBox.Text = as400File;
                        buildDataView(as400TextBox.Text);
                    }
                    else
                    {
                        as400TextBox.Text = "";
                        openFileDialog1.FileName = as400TextBox.Text;
                    }

                }

                private void uploadButton_Click(object sender, EventArgs e)
                {

                    Workbook workbook = Workbook.getWorkbook(new System.IO.FileInfo(as400TextBox.Text));
                    var sheet = workbook.getSheet(0);
                    uploadProgress.Maximum = sheet.getRows();
                    workbook.close();

                    backgroundWorker1.RunWorkerAsync((String)as400TextBox.Text);

                }

                private string as400File;

                private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
                {

                    appendMessage(((string)e.Argument));
                    Workbook workbook=null;            
                    workbook = Workbook.getWorkbook(new System.IO.FileInfo(((String)e.Argument)));
                    appendMessage("Workbook opened");            
                    var sheet = workbook.getSheet(0);
                    int r = 1;
                    string barcode, fname, lname, adname, student_id;
                    Cell[] row;
                    //uploadProgress.Maximum = sheet.getRows();

                    while (true)//process xls to SQL
                    {
                        try
                        {
                            row = sheet.getRow(r);
                        }
                        catch (IndexOutOfRangeException)
                        {
                            appendMessage("Processed: " + r);
                            workbook.close();
                            break;

                        }

                        student_id = ((string)row[0].getContents()).Trim();
                        barcode = ((string)row[1].getContents()).Trim();
                        lname = ((string)row[2].getContents()).Trim();
                        fname = ((string)row[3].getContents()).Trim();
                        adname = ((string)row[4].getContents()).Trim() + ((string)row[5].getContents()).Trim();

                        appendMessage(lname + " " + fname + " " + barcode + " " + adname + " " + student_id);
                        backgroundWorker1.ReportProgress(++r);
                    }


                }

                private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
                {
                    uploadProgress.Value = e.ProgressPercentage;
                    appendMessage("Status: " + (int)e.UserState);
                }

                private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
                {
                    appendMessage("Done!");
                }

                private void appendMessage(string msg)
                {

                    if (InvokeRequired)
                    {
                        messageBoxCallback mb = new messageBoxCallback(appendMessage);

                       this.Invoke(mb, new object[] { msg });//<---ObjectDisposedException

                       return;
                    }

                    messageBox.Text += (msg + Environment.NewLine);

                }


                private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
                {

                }


            }
        }


        Program.cs:

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Windows.Forms;

        namespace Importer
        {
            static class Program
            {
                /// <summary>
                /// The main entry point for the application.
                /// </summary>
                [STAThread]
                static void Main()
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());//<--TargetInvocationException (after ObjDisp is swallowed)
                }
            }
        }

    Stack Trace:
    System.ObjectDisposedException was unhandled by user code
      Message=Cannot access a disposed object.
    Object name: 'Form1'.
      Source=System.Windows.Forms
      ObjectName=Form1
      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 Importer.Form1.appendMessage(String msg) in C:\Users\Administrator\Google Drive\prj_tmp\Importer\Importer\Form1.cs:line 188
           at Importer.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in C:\Users\Administrator\Google Drive\prj_tmp\Importer\Importer\Form1.cs:line 163
           at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
           at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
      InnerException: 

If I swallow this exception I get:

System.Reflection.TargetInvocationException was unhandled
  Message=Exception has been thrown by the target of an invocation.
  Source=mscorlib
  StackTrace:
       at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       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.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       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(Int32 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 AlphaCardImporter.Program.Main() in C:\Users\Administrator\Google Drive\prj_tmp\Importer\Importer\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(Assembly 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.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.NullReferenceException
       Message=Object reference not set to an instance of an object.
       Source=AlphaCardImporter
       StackTrace:
            at AlphaCardImporter.Form1.backgroundWorker1_ProgressChanged(Object sender, ProgressChangedEventArgs e) in C:\Users\Administrator\Google Drive\prj_tmp\Importer\Importer\Form1.cs:line 173
            at System.ComponentModel.BackgroundWorker.OnProgressChanged(ProgressChangedEventArgs e)
            at System.ComponentModel.BackgroundWorker.ProgressReporter(Object arg)
       InnerException: 

2 个答案:

答案 0 :(得分:1)

当您在没有调试器的情况下运行时,可能会发生异常,您只是没有得到通知。在非调试运行中,当后台线程发生异常时,不会通知您,后台线程只是退出。

编辑代码以在异常发生时写入日志文件或其他内容,您可能会看到相同的行为。

答案 1 :(得分:0)

发现它!当我进行实验时,我正在调用遗留下来的垃圾。

这是违规行:

appendMessage("Status: " + (int)e.UserState); <-- there is no (int)e.UserState

当我在VS2010中没有调试的情况下运行时,我得到了一条更有意义的JIT运行时消息,这让我想到了这一行。