【问题标题】:Cross thread manipulate WPF control error: cannot跨线程操作WPF控件报错:不能
【发布时间】:2012-02-02 22:12:19
【问题描述】:

我在尝试操作 WPF 中的 FlowDocumentScrollViewer 控件时遇到了一个问题。我确实通过互联网搜索过这种错误,但发现我的问题非常独特。

这是代码:

    delegate void delg_FlowDoc(FlowDocument fdoc);

    //Function provided for both internal calling and outside calling 
    public void setfDocDisplay(FlowDocument fdoc)
    {

        FlowDocumentScrollViewer display = this.fDocDisplay;  //control to be operated

        if (display.Dispatcher.CheckAccess())
        {
            //called from own thread, just operate directly!

            string debug_check_ThreadName = Thread.CurrentThread.Name;
            if (debug_check_ThreadName == "Thread_MainUI")
            {

                //Debug only, now current thread MUST be the thread
                //created the UI!!!!
                display.Document = fdoc;  //<-- Error this line
            }
        }
        else
        {
            //called from other threads, use Invoke()!
            delg_FlowDoc pFun = new delg_FlowDoc(setfDocDisplay);
            this.Dispatcher.Invoke(pFun, new object[] { fdoc });

            //display.Dispatcher.Invoke(pFun, new object[] { fdoc });
            //this.Dispatcher.BeginInvoke(pFun, new object[] { fdoc });
        }
    }

并且在display.Document = fdoc; 行出现错误,表示仍然无法从其他线程访问控件。

这是错误的详细快照:

我很困惑,因为:

  1. 我已经执行了display.Dispatcher.CheckAccess(),以确保当前线程有权限对控制显示进行操作。

  2. 我再次添加debug_check_ThreadName 以确保它在那一刻处于正确的线程中。

  3. 我在另一个没有错误但较小的 WPF 项目中尝试了完全相同的代码

但仍然遇到同样的问题,告诉我我尝试从不同的线程进行操作。

我不熟悉 DispatcherInvoke 等属性的其他属性,所以我现在不知道如何解决这个问题。

如果有人可以给我这个错误的任何提示?

谢谢!

[已解决]

谢谢500 - 内部服务器错误

由于我仍然对这个事实感到震惊,我决定将我的理解放在问题中,以方便其他人遇到同样的问题并看到这个问题。

我现在已经解决了这个问题。这是因为 FlowDocument fdoc 实际上是一种 UI 控件,并且是在另一个线程中创建的。所以当主windows线程想要操作那个fdoc时——虽然它有FlowDocumentScrollViewer display的权限——它没有这个赋值语句中的其他控件fdoc的权限。

这很奇怪!我认为 fdoc 只是一个普通变量,如字符串或 int vars...>

【问题讨论】:

    标签: c# wpf multithreading invoke dispatcher


    【解决方案1】:

    问题不是您(尝试)分配给的控件,而是不是在 UI 线程上创建的源文档。

    【讨论】:

    • 而且 FlowDocument 不可冻结,因此您也无法共享它
    • 源文档与创建它的线程相关联——在这方面它就像一个 UI 控件。
    • @500-InternalServerError !!问题解决了!!!谢谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    • 那么就像FlowDocument对象是一种UI控件而不是像string这样的普通变量?这点太难理解了……
    • 是的,我相信原因是它具有依赖于创建它的输出设备的属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多