线程安全调用带参数

时间:2015-11-19 04:10:36

标签: c# multithreading thread-safety

我尝试启动一个新线程,对多个列表进行排序,然后将富文本框中的数据设置为排序时间。

我的代码是:

delegate void TextCallback(string data);
private void button1_Click(object sender, EventArgs e)
    {
        List<List<int>> data = new List<List<int>>();

        for(int i = 0; i < 8; i++)
        {
            data.Add(new List<int>());
        }
        Random rand = new Random();

        for(int j = 0; j < 1000000; j++)
        {
            foreach(var l in data)
            {
                l.Add(rand.Next(0, 10000));
            }
        }

        Thread singleThreaded = new Thread(() => doSortOnMultiList(data));
        singleThreaded.Start();

    }
    private void doSortOnMultiList(List<List<int>> lists)
    {
        Stopwatch s = new Stopwatch();
        s.Start();

        foreach(var list in lists)
        {
            list.Sort();
        }

        s.Stop();

        //SetTextBox2(richTextBox2.Text + "Single-Threaded sort: " + s.Elapsed.Milliseconds);
        SetTextBox2("Single-Threaded sort: " + s.Elapsed.Milliseconds + "ms." + System.Environment.NewLine);
    }
    private void SetTextBox2(string data)
    {
        if (richTextBox2.InvokeRequired)
        {
            Invoke(new TextCallback(SetTextBox2), new object[] { data });
        }
        else
            //richTextBox2.Text = data;
            richTextBox2.Append(data);
    }

我正在使用msdn文档,它说上面的方法是线程安全的,并允许我的程序在我的线程中设置文本。但事实并非如此,因为我收到以下错误:

跨线程操作无效:控制&#39; richTextBox2&#39;

我的实现中唯一不同的东西(从我可以看到)是我用lambda启动线程,以便我能够传入我的列表。我不能在线程中掌握一些概念,所以任何帮助都会受到赞赏。

以下是我目前使用的MSDN资源:MSDN

编辑:我修复了上面的代码,旧行被注释掉,以显示跟我有什么不同之处。

1 个答案:

答案 0 :(得分:2)

您在一个单独的主题

上调用了doSortOnMultiList()
Thread singleThreaded = new Thread(() => doSortOnMultiList(data));
singleThreaded.Start();

在此doSortOnMultiList()内,有

SetTextBox2(richTextBox2.Text + "Single-Threaded sort: " + s.Elapsed.Milliseconds);

并在此行内,有

richTextBox2.Text

基本上,您正在从非UI线程访问UI组件richTextBox2,这会导致此错误。