[英]Datagridview with System.Threading.Timer
这个问题导致程序运行几分钟。 在我使用System.Timers.Timer
之前没有发现问题,直到我改为System.Threading.Timer
。
我想知道......
这个问题的根本原因是什么?
如何解决这个问题呢 ?
A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>InternetCafe.vshost.exe</AppDomain><Exception><ExceptionType>System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>BindingSource cannot be its own data source. Do not set the DataSource and DataMember properties to values that refer back to BindingSource.</Message><StackTrace> at System.Windows.Forms.BindingSource.get_Count()
at System.Windows.Forms.CurrencyManager.get_Count()
at System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e)
at System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e)
at System.ComponentModel.BindingList`1.Child_PropertyChanged(Object sender, PropertyChangedEventArgs e)
at InternetCafe.Computer.NotifyPropertyChanged(String info) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\Computer.cs:line 163
at InternetCafe.Computer.UsedTimeValueChanged(Object sender, PropertyChangedEventArgs e) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\Computer.cs:line 149
at InternetCafe.TimerManager.OnTimeChanged(PropertyChangedEventArgs e) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\TimerManager.cs:line 62
at InternetCafe.TimerManager.set_TimeSinceStartTime(TimeSpan value) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\TimerManager.cs:line 30
at InternetCafe.TimerManager.tmrThreadingTimer_TimerCallback(Object state) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\TimerManager.cs:line 50
at System.Threading._TimerCallback.TimerCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading._TimerCallback.PerformTimerCallback(Object state)</StackTrace><ExceptionString>System.InvalidOperationException: BindingSource cannot be its own data source. Do not set the DataSource and DataMember properties to values that refer back to BindingSource.
at System.Windows.Forms.BindingSource.get_Count()
at System.Windows.Forms.CurrencyManager.get_Count()
at System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e)
at System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e)
at System.ComponentModel.BindingList`1.Child_PropertyChanged(Object sender, PropertyChangedEventArgs e)
at InternetCafe.Computer.NotifyPropertyChanged(String info) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\Computer.cs:line 163
at InternetCafe.Computer.UsedTimeValueChanged(Object sender, PropertyChangedEventArgs e) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\Computer.cs:line 149
at InternetCafe.TimerManager.OnTimeChanged(PropertyChangedEventArgs e) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\TimerManager.cs:line 62
at InternetCafe.TimerManager.set_TimeSinceStartTime(TimeSpan value) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\TimerManager.cs:line 30
at InternetCafe.TimerManager.tmrThreadingTimer_TimerCallback(Object state) in C:\Users\at0m\Documents\Visual Studio 2010\Projects\InternetCafe\InternetCafe\TimerManager.cs:line 50
at System.Threading._TimerCallback.TimerCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading._TimerCallback.PerformTimerCallback(Object state)</ExceptionString></Exception></TraceRecord>
TimerManager类
物业TimeSinceStartTime
public TimeSpan TimeSinceStartTime
{
get { return new TimeSpan(timeSinceStartTime.Hours, timeSinceStartTime.Minutes, timeSinceStartTime.Seconds); }
set
{
if (timeSinceStartTime != value)
{
timeSinceStartTime = value;
OnTimeChanged(new PropertyChangedEventArgs("TimeSinceStartTime"));
}
}
}
TimerManager构造函数
public TimerManager(frmMainServer main)
{
_timer = new System.Threading.Timer(new
TimerCallback(tmrThreadingTimer_TimerCallback),
null, System.Threading.Timeout.Infinite, 1000);
_main = main;
}
OnTimeChanged
private void OnTimeChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
定时器回调
private void tmrThreadingTimer_TimerCallback(object state)
{
TimeSinceStartTime += TimeSpan.FromSeconds(1);
}
电脑课
重要财产
public decimal TotalMoney
{
get
{
return this.totalMoney;
}
set
{
if (value != this.totalMoney)
{
this.totalMoney = value;
NotifyPropertyChanged("TotalMoney");
}
}
}
public TimerManager UsedTime
{
get
{
return this.usedTimeValue;
}
set
{
if (value != this.usedTimeValue)
{
this.usedTimeValue = value;
NotifyPropertyChanged("UsedTimeValue");
usedTimeValue.PropertyChanged += new PropertyChangedEventHandler(UsedTimeValueChanged);
}
}
}
如果时间变更计算费用,请通知Usedtime和TotalMoney。
private void UsedTimeValueChanged(object sender, PropertyChangedEventArgs e)
{
NotifyPropertyChanged("UsedTime");
this.totalMoney = (decimal)(this.UsedTime.TimeSinceStartTime.Hours * this.session.Member.MemberTariff + this.UsedTime.TimeSinceStartTime.Minutes * (this.session.Member.MemberTariff / 60));
NotifyPropertyChanged("TotalMoney");
}
主要表格
使用dbBindingSource设置CompList gridview数据源,并使用Computers绑定列表设置dbBindingSource数据源。
public BindingList<Computer> computers = new BindingList<Computer>();
.
.
.
compList.DataSource = dbBindingSource;
dbBindingSource.DataSource = computers;
根本原因是您正在更改绑定到UI控件的非UI线程中的数据源。 最简单的解决方案是使用System.Windows.Forms.Timer ,它始终在UI线程上执行,但是,它的分辨率不是很高或准确。 下一个选项是确保使用SynchronizationContext或使用Invoke / BeginInvoke在UI线程上引发PropertyChanged。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.