【问题标题】:DataGridView and Multi-ThreadingDataGridView 和多线程
【发布时间】:2015-09-28 20:34:50
【问题描述】:

我正在尝试将我的 foreach 方法转换为多线程。

我有一个datagridview,该方法从cell[0](包含一个url)获取值并将其发送到另一个与httpwebrequest一起使用的方法。

public void UrlCheck()
{
    foreach (DataGridViewRow row in dataUrlList.Rows)
    {
        string url= row.Cells[0].Value.ToString();
        try
        {
            string get = getHtml(url);
            //work with get string removed
            if()
            {
                row.Cells[1].Value = "page info here";
            }
            else
            {
                row.Cells[1].Value = "error info here";
            }
        }
        catch
        {
        }                       
    }
    MessageBox.Show("Done.");
}

上面的代码是按顺序运行的,没有任何问题。

然后我尝试将此代码转换为多线程:

按钮:

private void button9_Click(object sender, EventArgs e)
{
    int threadcount = Convert.ToInt32(numThreadSearch.Value);
    ThreadForSearch = new Thread[threadcount];
    checkingForSearch = dataUrlList.Rows.Count;
    isRunningForSearch = true;
    beenCheckedForSearch = 1;

    for (int i = 0; i <= threadcount - 1; i++)
    {
        ThreadForSearch[i] = new Thread(new ParameterizedThreadStart(MultiThreadMet));
        ThreadForSearch[i].Start(i);
    }
}

多线程方法在这里:

public void MultiThreadMet (object IndexForSearch)
{                
    int index = (int)IndexForSearch;
    DataGridViewRow row = dataUrlList.Rows[index];

    while (isRunningForSearch)
    {
        try
        {
            if (beenCheckedForSearch >= checkingForSearch)
            {
                isRunningForSearch = false;
            }

            if (index >= dataUrlList.Rows.Count)
            {
                ThreadForSearch[index].Abort();
            }                     

            //For just test i'm trying to add "test" in every cell[1] in datagridview
            dataUrlList.Invoke(new Action(() => row.Cells[1].Value = "test"));

            beenCheckedForSearch++;  
        }
        catch
        {
        }                           
    }
    ThreadForSearch[1].Abort();    
}

它从 numericUpDown 控件中获取线程计数,如果我从 numericUpDown 中选择值 10,它会在 datagridview 的前 10 个单元格中放置“测试”文本,然后停止,如果我选择 4(或 2,5 ,7),然后它将“测试”文本放在前 4(2,5,7) 个单元格中并停止。

线程结束后不会继续下一行。所以我试图触发 5 个线程(我总是从 numericUpDown 中选择它),当一个线程完成工作时,它必须转到下一行。我该如何解决这个问题?

还声明了这些变量:

Thread[] ThreadForSearch;
int beenCheckedForSearch;
int checkingForSearch;
private bool isRunningForSearch;

从输出屏幕我得到

Exception thrown: 'System.Threading.ThreadAbortException' in mscorlib.dll

谢谢。

【问题讨论】:

  • 不清楚是什么问题?如果值为 10 是否有效?选择4(或2,5,7)时是否有效?什么有效,什么无效? (同样正确缩进你的代码会让其他人更容易阅读)。
  • 感谢您的回复 codersl,问题是假设我在 datagridview 中有 50 行,但是如果我从 numericUpDown 中选择 10 个线程,它只会写入 10 行并且不会完成线程和继续下一行。
  • 啊,我明白了,那么您的问题是每个线程都传递了一个永远不会更改的“索引”,因此它只会处理一行。我仍然不确定您要做什么...每个线程应该处理哪些行?
  • 再次感谢 codersl,我已经编辑了问题。线程完成工作后,它应该移动到下一行,但它没有。
  • "每个线程都传递了一个永远不会改变的'索引'"

标签: c# multithreading


【解决方案1】:

index 计数器未在线程方法中递增。

程序中仍然存在重叠问题,我将让您解决。假设有 50 个 url,问题是线程 1 将单元格 0 更新为 49,线程 2 将单元格 1 更新为 49,依此类推。

public void MultiThreadMet (object IndexForSearch)
{                
    int index = (int)IndexForSearch;

    while (isRunningForSearch)
    {
        try
        {
            if (index >= dataUrlList.Rows.Count)
            {
                return;
            }

            DataGridViewRow row = dataUrlList.Rows[index];
            index++;

            //For just test i'm trying to add "test" in every cell[1] in datagridview
            dataUrlList.Invoke(new Action(() => row.Cells[1].Value = "test"));
        }
        catch
        {
        }                           
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 2013-09-16
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多