Laden...

"Der Index lag außerhalb des Bereichs" in BackGroundWorker, aber nicht im Einzelschrittmodus

Erstellt von Maliko vor 10 Jahren Letzter Beitrag vor 10 Jahren 4.392 Views
M
Maliko Themenstarter:in
117 Beiträge seit 2012
vor 10 Jahren
"Der Index lag außerhalb des Bereichs" in BackGroundWorker, aber nicht im Einzelschrittmodus

Hi,

ich hab hier momentan ein sehr merkwürdiges Problem und komme einfach nicht weiter. Und zwar habe ich eine Methode, welche im BackgroundWorker arbeitet. Doch sobald ich diese Ausführe crasht das Programm mit der Fehlermeldung: > Fehlermeldung:

"Ein Aufrufziel hat einen Ausnahmefehler verursacht."

Wenn ich die Funktion nun im Einzelschrittmodus durchlaufe um zu schauen, wo genau er rausspringt, dann passiert gar nichts und die Funktion läuft problemlos durch. Nehm ich den Breakpoint anschließend wieder raus, crasht es wieder.

Hier die Funktion:

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        SharePointHandler sp = new SharePointHandler();
        sp.Context = m_Context;
        for (int i = 0; i < m_fileList.Count(); i++)
        {
            bool success = sp.UploadFile(m_Library, m_FolderName, m_fileList[i], false);
            if (!success)
            {
                DialogResult result = MessageBox.Show("Es ist bereits eine Datei mit diesem Namen vorhanden. Soll diese überschrieben werden?", "Datei überschreiben?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    bool secondTry = sp.UploadFile(m_Library, m_FolderName, m_fileList[i], true);
                    if (secondTry)
                        radGridView1.BeginInvoke(new Action(() => { radGridView1.Rows[i].Cells[1].Value = Properties.Resources.accept; }));
                }
                else
                    radGridView1.BeginInvoke(new Action(() => { radGridView1.Rows[i].Cells[1].Value = Properties.Resources.cancel; }));
            }
            else
                radGridView1.BeginInvoke(new Action(() => { radGridView1.Rows[i].Cells[1].Value = Properties.Resources.accept; }));  //Das hier ist Zeile 108
        }
    }
    catch (Exception es)
    {   
        MessageBox.Show(es.ToString());
    }
            
}

Und hier die Fehlermeldung der InnerExecption inkl. Stacktrace:> Fehlermeldung:

{"Der Index lag außerhalb des Bereichs. Er muss nicht negativ und kleiner als die Auflistung sein.\r\nParametername: index"}

bei System.ThrowHelper.ThrowArgumentOutOfRangeException()
bei System.Collections.Generic.List1.get_Item(Int32 index) bei Telerik.WinControls.Data.RadListSource1.get_Item(Int32 index)
bei Telerik.WinControls.UI.GridViewRowCollection.get_Item(Int32 index)
bei SharepointBrowser.UploadForm.<>c__DisplayClass7.<worker_DoWork>b__3() in C:\Users[...]\UploadForm.cs:Zeile 108.

Hat da vielleicht irgendjemand von euch eine Ahnung, warum er problemlos durchläuft, wenn ich im Einzelschrittmodus bin, im normalen aber Crasht?

Danke schon mal im Vorraus
Maliko

Edit: Vielleicht noch interessant zu wissen, das wenn ich die Funktion normal laufen lasse (also ohne zweiten Thread, dann läuft sie auch problemlos durch).

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo Maliko,

klingt danach, als würde sich z.B. m_fileList.Count ändern, während die Schleife durchlaufen wird.

Stelle sicher, dass es keine gleichzeitigen Zugriffe auf gemeinsame Daten gibt.

herbivore

M
Maliko Themenstarter:in
117 Beiträge seit 2012
vor 10 Jahren

Da wird leider nichts geändert. Der Backgroundworker wird ganz am ende der Form_Load-Events aktiviert und zwischendrin macht das System sonst gar nix.

Hier auch noch die andere Funktion:

private void UploadForm_Load(object sender, EventArgs e)
{
    DataTable dataSource = new DataTable();
    dataSource.Columns.Add("Dateiname");          

            
    foreach (string item in m_fileList)
    {
        FileInfo info = new FileInfo(item);
        DataRow row = dataSource.NewRow();
        row["Dateiname"] = info.Name;
        dataSource.Rows.Add(row);
    }

    radGridView1.DataSource = dataSource;
    radGridView1.Columns["Dateiname"].Width = 160;

    GridViewImageColumn imageColumn = new GridViewImageColumn();
    imageColumn.Name = "ImageColumn";
    imageColumn.FieldName = "Result";
    imageColumn.HeaderText = " ";
    imageColumn.ImageLayout = ImageLayout.None;   
    radGridView1.MasterTemplate.Columns.Add(imageColumn);
    cmd_Close.Enabled = false;

    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.RunWorkerAsync();
}

Ansonsten gibt es nur noch ein Button_Click-Event, welches das Fenster schließt. Der Index kann sich also meines wissens nach gar nicht ändern.

4.939 Beiträge seit 2008
vor 10 Jahren

Stichwort: Closure bzw. Capture(d) Variable
Du benutzt den Schleifenzähler innerhalb eines Lambda-Ausdrucks.

Aber da sind noch andere Dinge, die unschön sind:

  • MessageBox innerhalb des BackgroundWorker-Threads
  • Zugriff auf UI-Elemente (auch wenn du sie per BeginInvoke ansprichst) - besser ist es das ProgressChanged-Ereignis dafür zu benutzen (da dieser explizit im UI-Thread läuft)
M
Maliko Themenstarter:in
117 Beiträge seit 2012
vor 10 Jahren

Danke dir. Der Tipp war Gold wert. Jetzt funzt es.

849 Beiträge seit 2006
vor 10 Jahren

Und um herauszubekommen wo es nun wirklich knallt ->Debug -> Exceptions und haken beim managed RUntime Exceptions setzten. Der Debugger sollte dann genau an der Fehlerstelle halt machen.