跨线程操作WPF控件错误:不能
我在尝试操作 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;
行中发生错误,表示仍然无法从不同的线程访问该控件。
这是错误的详细快照:
我很困惑,因为:
我已经执行了
display.Dispatcher.CheckAccess() 确保当前线程有对控件显示进行操作的权限。
我再次添加一个
debug_check_ThreadName
以双重确保它当时处于正确的线程中。我在另一个较小的 WPF 项目中尝试了完全相同的代码,没有错误
,但仍然遇到同样的问题告诉我我尝试从不同的线程进行操作。
我不熟悉 Dispatcher 或 Invoke 等属性的其他属性,所以我现在不知道如何解决这个问题。
如果有人能给我任何关于这个错误的提示吗?
谢谢你!
[已解决]
谢谢500 - 内部服务器错误!
由于我仍然对这个事实感到震惊,所以我决定将我的理解放在这个问题中,以方便其他有同样问题并看到这个问题的人。
我现在已经解决了这个问题。这是因为FlowDocument fdoc实际上是一种UI控件,并且是在另一个线程中创建的。因此,当主窗口线程想要操作该 fdoc 时,尽管它具有 FlowDocumentScrollViewer 显示 的权限,但它没有对该赋值语句中的其他控件 fdoc 的权限。
确实比较奇怪!!我认为 fdoc 只是一个普通变量,如字符串或 int 变量... ><
I came across a problem while trying to manipulate the FlowDocumentScrollViewer control in WPF. I did searched through the internet about this kind of error, but found my problem is quite unique.
this is the code:
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 });
}
}
And an error occurred in line display.Document = fdoc;
, saying still cannot access the control from a different thread.
And this is the detailed snapshot of error:
I am confused since:
I have already performed
display.Dispatcher.CheckAccess()
to ensure current thread has the permission to operate on the control display.I again add a
debug_check_ThreadName
to double ensure it's in the right thread for that moment.I tried exactly the same code in another but smaller WPF project that is free of errors
But still got the same problem telling me I try to operate from a different thread.
I am not familiar with other properties of Dispatcher or Invoke etc. properties so I have no idea now to solve this problem.
If anyone can give me any hint of this error?
Thank you!
[SOLVED]
Thank you 500 - Internal Server Error!
Since I am still shocked by the fact, I decide to put my understanding in the question to facilitate some one else have the same problem and saw this question.
I have now fixed the problem. It is because the FlowDocument fdoc is actually a type of UI control and created in another thread. So when the main windows thread want to operate that fdoc - although it has permission to FlowDocumentScrollViewer display - it doesn't have permission to the other control fdoc in this assignment sentence.
It's rather weird!! I thought fdoc is just a normal variable like a string or int vars... ><
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题不在于您(尝试)分配给哪个控件,而在于源文档不是在 UI 线程上创建的。
It is not the control you (try to) assign to that's the problem - it's the source document that's not created on the UI thread.