即使我使用线程安全调用,也会发生跨线程操作无效异常

时间:2013-08-01 13:54:37

标签: c# .net winforms

以下是我的ThreadSafe功能的代码

public static void ThreadSafe(Action action)
        {
             System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
             new MethodInvoker(action));
        }

我正在使用此ThreadSafe函数来访问各种跨线程操作。它在其他类中工作正常,但当我在面板Comment中添加用户控件commentContainer时,它显示以下错误。

  

跨线程操作无效异常

按照其代码截图: enter image description here

我想将comment字符串传递给此控件。控制处理基于该值。 我认为我使用这个功能的方式是错误的。任何人都可以改进我的代码,如果它不正确?如果正确的话请告诉我如何解决这个问题?

另请注意,当我删除foreach循环时,后台工作程序正常工作。

setTopicInfo()代码:

public void setTopicInfo()
        {
            try
            {
                TopicInfo.Text = "Topic Views: " + dops.getVisiteds(tid) + " | " +
                    "People Involved: " + dops.getPeopleInvolved(tid) + " | ";
            }
            catch (Exception)
            { TopicInfo.Text = "[Some error occured while loading Topic Information. Please reopen or refresh this topic.] | "; }
        }

3 个答案:

答案 0 :(得分:2)

Dispatcher.CurrentDispatcher为当前线程返回Dispatcher。在此示例中,ThreadSafe方法在当前线程上调用Action,而不是在创建commentContainer的线程上调用(通常称为UI线程)。

WinForms有助于通过Control.InvokeControl.BeginInvoke方法在UI线程上调用代码。对此示例的快速单行修复是通过调用Main.ThreadSafecommentContainer.Invoke来将呼叫替换为commentContainer.BeginInvoke。您也可以利用BackgroundWorker.ProgressChanged事件,比如Bill Sambrone的建议。

答案 1 :(得分:1)

您的ThreadSafe方法在从bgw线程调用时建立Dispatcher。

这就是MSDN对Dispatcher.CurrentDispatcher所说的话:

  

如果Dispatcher未与当前线程关联,则将创建新的Dispatcher。

请改用Application.Dispatcher。请参阅示例this SO question

答案 2 :(得分:1)

由于您使用的是BackgroundWorker,因此可以使用其报告进度的功能来设置注释。如果要从代码创建BWWorker,可以通过设计器创建ReportProgress事件处理程序,也可以将其添加到代码中。确保为ReportsProgress启用标志。

然后,在你的foreach循环中:

backgroundWorker1.ReportProgress(yourdatagoeshere)

在backgroundWorker1_ReportsProgress方法中,您可以将该数据传递给addComment方法。