将参数传递给后台工作线程



我正在运行一个带有后台worker的c#代码。我实现它有一个foreach循环,并在循环内传递foreach变量作为Backgroundworker的参数。但问题是,每当我运行代码只有一个随机值,最有可能在gridview的最后一行作为参数传递。代码如下

foreach (DataGridViewRow row in dataGridView3.Rows)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.WorkerSupportsCancellation = true;
    worker.DoWork += delegate
    {
        data = dataGridView3.Rows[row.Index].Cells[0].Value.ToString();
        rowindex = row.Index;
        data1 = ros[0].Cells[0].Value.ToString();
    };
    worker.RunWorkerAync();
}

尝试发送参数为row

worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
    DataGridViewRow  dgr = (DataGridViewRow)args.Argument;
    data = dataGridView3.Rows[dgr.Index].Cells[0].Value.ToString();
    rowindex = dgr.Index;
    data1 = dgr[0].Cells[0].Value.ToString();
};
worker.RunWorkerAsync(row);

除了@Damith的答案,您还可以在局部作用域中捕获foreach变量。

foreach (DataGridViewRow row in dataGridView3.Rows)
{
    DataGridViewRow copy = row; // captured!
    BackgroundWorker worker = new BackgroundWorker();
    worker.WorkerSupportsCancellation = true;
    worker.DoWork += delegate
    {
        data = dataGridView3.Rows[copy.Index].Cells[0].Value.ToString();
        rowindex = copy.Index;
        data1 = copy[0].Cells[0].Value.ToString();
    };
    worker.RunWorkerAync();
}

这是因为row变量在每次迭代中绑定到不同的值,因此您在最后一次迭代中获得row的值。

Eric lippert的博客和这个答案都有解释。

看起来像

data = dataGridView3.Rows[row.Index].Cells[0].Value.ToString();

可以修改为:

data = row.Cells[0].Value.ToString();

,因为它有点违背了foreach语句的整个目的。另外,下面这行似乎有一个打字错误:

data1 = ros[0].Cells[0].Value.ToString();

我不确定您打算data1包含什么,但您可能要考虑简单地将BackgroundWorkerforeach语句中传递DataGridView row变量,然后在DoWork方法中取出必要的数据。

最新更新