尽管设置了ApartmentState,但仍存在跨线程错

时间:2013-03-04 09:48:41

标签: c# multithreading

我正在尝试将循环内容显示到我的UI。首先,我不确定我是以正确的方式接近这个(使用WinForms),但这就是我正在做的事情:

foreach (string item in stringArray)
{
        Thread thread = new Thread(delegate()
                              {
                                  UpdatedResultEvent(item);
                              });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
}

我希望这是足够的信息,但如果不是,那么我将在这里详细介绍。

我有两个类,我的Program.cs(WinForm)和另一个名为logicClass的类。我将我的Program对象的实例传递给我的logicClass。我的logicClass有一个委托,该签名与我的Program类中的方法匹配。作为委托传递的方法是

public void UpdateResultsOnScreen(string newContent)
{
txtResults.Text += newContent;
}

错误消息是

  

跨线程操作无效:从线程访问控制   除了在

上创建的主题

修改

与进度条的工作方式类似,目标是让控件实时更新。目前,即使它确实有效,线程也不会将“结果”返回到屏幕,直到线程完成。

3 个答案:

答案 0 :(得分:1)

即使您正在设置ApartmentState,也必须在从另一个(非UI)线程访问时调用UI控件。

确保在UpdateResultEvent方法中调用UI控件。

无论如何,你正在做的不是一个好主意,考虑使用ThreadPoolParallel.ForEach

它会自动扩展你的代码,产生一堆线程可以真正降低性能,特别是如果你的集合中有很多项目。

答案 1 :(得分:1)

使用它(如果你在WinForms上):

public void UpdateResultsOnScreen(string newContent)
{
    txtResults.BeginInvoke(
        new Action<string>((value) =>
        {
            txtResults.Text += value;
        }),
        newContent);
}

同样,动画线表示,请考虑使用ThreadPoolParallel.ForEach

答案 2 :(得分:0)

这样做怎么样?

 public void UpdateResultsOnScreen(string newContent)
    {
        if(txtResults.InvokeRequired)
        {
            txtResults.Invoke(
                new Action<string>(content => txtResults.Text += content), newContent);
            return;
        }
        txtResults.Text += newContent;
    }