简体   繁体   中英

Why do I get TargetInvocationException in my threaded C# application?

Here is the code (in a simple form):

delegate DataTable Functie();
Functie deleg;

DataTable find1()
{
    return new DataTable();
}
DataTable find2()
{
    return new DataTable();
}


private void btnFind1_Click(object sender, EventArgs e)
{
    deleg = this.find2;
    backgroundWorker1.RunWorkerAsync();
}


private void btnFind2_Click(object sender, EventArgs e)
{
    deleg = this.find1;
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker bk = sender as BackgroundWorker;
    e.Result = deleg;

    if (bk.CancellationPending)
    {
        e.Cancel = true;
    }
}


private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        MessageBox.Show("Operation was canceled");
    }
    else if (e.Error != null)
    {
        MessageBox.Show("An error occurred: " + e.Error.Message);
    }
    else
    {
        dataGridView1.DataSource = (DataTable)e.Result;
    }
}

So, basically I have 2 functions find1 and find2 and these are long-time-processing functions. I want to run these 2 functions on an BackgroundThread so I created a delegate. When i call one function, the delegate takes the address of a function or the other. When I start the thread, I pass the delegate instead of directly typing the function, so I won't create 2 background threads, each with its own events and stuff. But I run into problems, when I run the program, the following error is thrown:

"System.Reflection.TargetInvocationException was unhandled
Exception has been thrown by the target of an invocation."

It has to do with the delegate passed to the thread. I can, of course, write everything simpler with conditions to see what functions has to be ran, but I got into this and I didn't know how to solve it. I want to know what I did wrong.

I think, in your DoWork function, you need to call the delegate like this:

e.Result = deleg();

The reason is that this will actually invoke the function, rather than just set the result equal to a reference to the function.

You're casting a delegate to a DataTable :

dataGridView1.DataSource = (DataTable)e.Result;

which came from here:

e.Result = deleg;

Did you mean:

e.Result = deleg();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM