停止时重新启动线程

时间:2017-10-13 04:55:14

标签: c# multithreading

在问题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#上实现上述概念?

1 个答案:

答案 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秒钟保存不超过一次,只有在有一次或多次更改时才会保存。