【发布时间】:2015-10-19 08:43:39
【问题描述】:
我正在尝试绑定一个 TextBox 以在 Windows 窗体中记录错误。
我像这样绑定文本框:
this.operationEventHistoryTextbox.DataBindings.Add("Text", this.Logger, "OperationLog")
Logger 对象是 Logger 类的一个实例,它包含以下属性。
public string OperationLog
{
get
{
return this.operationLog;
}
set
{
if (this.operationLog != value)
{
this.operationLog = value;
System.ComponentModel.PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new System.ComponentModel.PropertyChangedEventArgs("OperationLog"));
}
}
}
}
我在调用this.Logger.LogEvent("message") 时收到错误消息。我的LogEvent 方法包含以下内容:
public void LogEvent(string msg)
{
this.OperationLog += System.DateTime.Now + ": " + msg + "\r\n";
}
InvalidOperationException 表示存在无效的跨线程操作,并且控件operationEventHistoryTextBox 是从创建它的线程之外的线程访问的。
我理解这意味着我以非线程安全的方式编写了部分代码,但我真的不明白为什么,或者要修复什么。
我可以将所有这些函数设置为调用而不是直接调用,但我想真正了解什么不起作用。
更新:我尝试使用 System.Threading.ScynchronizationContext 在正确的线程上引发 PropertyChanged 事件,但是,我继续收到错误。这是该属性的新设置器:
set
{
if (this.operationLog != value)
{
System.Threading.SynchronizationContext context = System.Threading.SynchronizationContext.Current
?? new System.Threading.SynchronizationContext();
this.operationLog = value;
context.Send(
(s) =>
{
System.ComponentModel.PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new System.ComponentModel.PropertyChangedEventArgs("OperationLog"));
}
},
null);
}
}
我没有正确创建SynchronizationContext 吗?还是这里有其他工作?
更新 2:
如果我将handler(this, ... ) 的调用替换为handler(null, ... ) 或handler(this.OperationLog),则setter 将正常运行,但不会实际更新文本。
现在我正在使用我将使用的解决方法,而不是使用 DataBinding 来链接文本,只需通过将我自己的处理程序添加到 PropertyChanged 事件来手动执行此操作。
【问题讨论】:
标签: c# multithreading winforms data-binding