线程停止时重新启动 [英] Restart the thread when it will stop

查看:112
本文介绍了线程停止时重新启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在问题中

现在,如果顺序删除两个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#上实现上述概念?

解决方案

我将建议使用Microsoft的Reactive Framework. NuGet"System.Reactive".

然后您可以执行以下操作:

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秒保存一次,并且仅在进行一次或多次更改时保存.

In the question Why I need to overload the method when use it as ThreadStart() parameter?, I got the following solution for saving file in separate thread problem (it's required to save file when delete or add new instance of the 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);

}

Now, if sequentially delete two instances of the PersonEntity, System.Threading.ThreadStateException: Thread is still executing or don't finished yet. Restart is impossible. will occur.`.

I understand this exception meaning as a whole, however, the following solution will not be enough: next time, the file will not be saved.

if (!dataFileTransactionsThread.IsAlive) {
    dataFileTransactionsThread.Start(allStaff);
}

Probably, it't better to restart the thread when it finished, and then save the file again. However, it's also required to provide the code for the case when will be deleted sequentially three or more instances. Just on the conception level, it's simple: we need only newest allStaff collection, so the previous unsaved allStaff collections or not necessary anymore.

How can I realize above concept on C#?

解决方案

I'm going to suggest using Microsoft's Reactive Framework. NuGet "System.Reactive".

Then you can do this:

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");
        });

This code will watch your allStaff collection for all changes and then, for every change, it will wait 2 seconds to see if any other changes come thru and if they don't it then takes a copy of your collection (this is crucial for threading to work) and it saves your collection.

It will save no more than once every 2 seconds and it will only save when there has been one or more changes.

这篇关于线程停止时重新启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆