在问题Why I need to overload the method when use it as ThreadStart() parameter?中,我得到了以下解决方案,用于将文件保存在单独的线程问题中(删除时需要保存文件或添加PersonEntity
的新实例):
private ObservableCollection<PersonEntitiy> allStaff;
private Thread dataFileTransactionsThread;
public staffRepository() {
allStaff = getStaffDataFromTextFile();
dataFileTransactionsThread = new Thread(UpdateDataFileThread);
}
public void UpdateDataFile(ObservableCollection<PersonEntitiy> allStaff)
{
dataFileTransactionsThread.Start(allStaff);
// If you want to wait until the save finishes, uncomment the following line
// dataFileTransactionsThread.Join();
}
private void UpdateDataFileThread(object data) {
var allStaff = (ObservableCollection<PersonEntitiy>)data;
System.Diagnostics.Debug.WriteLine("dataFileTransactions Thread Status:"+ dataFileTransactionsThread.ThreadState);
string containsWillBeSaved = "";
// ...
File.WriteAllText(fullPathToDataFile, containsWillBeSaved);
System.Diagnostics.Debug.WriteLine("Data Save Successfull");
System.Diagnostics.Debug.WriteLine("dataFileTransactions Thread Status:" + dataFileTransactionsThread.ThreadState);
}
现在,如果按顺序删除PersonEntity
的两个实例,则会发生System.Threading.ThreadStateException: Thread is still executing or don't finished yet. Restart is impossible.
。
我理解这个异常意味着整体,但是,以下解决方案是不够的:下次,文件将不会被保存。
if (!dataFileTransactionsThread.IsAlive) {
dataFileTransactionsThread.Start(allStaff);
}
可能最好在完成后重新启动线程,然后再次保存文件。但是,还需要为将要按顺序删除三个或更多实例的情况提供代码。只是在概念层面,它很简单:我们只需要最新的allStaff
集合,所以以前未保存的allStaff
集合或者不再需要。
如何在C#
上实现上述概念?
答案 0 :(得分:2)
我打算建议使用微软的Reactive Framework。 NuGet&#34; System.Reactive&#34;。
然后你可以这样做:
IObservable<List<PersonEntity>> query =
Observable
.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
h => allStaff.CollectionChanged += h, h => allStaff.CollectionChanged -= h)
.Throttle(TimeSpan.FromSeconds(2.0))
.Select(x => allStaff.ToList())
.ObserveOn(Scheduler.Default);
IDisposable subscription =
query
.Subscribe(u =>
{
string containsWillBeSaved = "";
// ...
File.WriteAllText(fullPathToDataFile, containsWillBeSaved);
System.Diagnostics.Debug.WriteLine("Data Save Successful");
});
此代码会针对所有更改观看您的allStaff
集合,然后,对于每次更改,它将等待2秒钟以查看是否有任何其他更改通过,如果他们没有,则需要副本您的收藏(这对于线程化工作至关重要)并保存您的收藏。
每2秒钟保存不超过一次,只有在有一次或多次更改时才会保存。