Понять, когда параллельная задача закончилась запись файла - PullRequest
0 голосов
/ 10 октября 2018

Я написал ac # windows service;при запуске службы, 2 задачи выполняются.Первая задача - очень быстро прочитать данные с какого-либо устройства (примерно каждые 10/20 мсек) и сохранить данные в объекте очереди.Вторая задача (медленно ... примерно каждые 3/5 секунды) - извлечь данные из очереди и сохранить их на диске.При остановке службы, будет также остановлено 2 задачи.Первое задание (чтение данных) немедленно, второе задание (получение данных из очереди и сохранение) после некоторого контроля.Чтение может быть в порядке, но задача сохранения данных за некоторое время до финиша или в критическом состоянии остановила мое приложение ..

Мой код ..

private CancellationTokenSource tokenSource = null;
private Task task = null;
System.Timers.Timer timerTask1 = null;        

private CancellationTokenSource tokenSource1 = null;
private Task task1 = null;
System.Timers.Timer timerTask2 = null;

Queue<string> dataQueue = new Queue<string>();
StringBuilder sb = new StringBuilder();

private void startTask()
{
    this.tokenSource = new CancellationTokenSource();
    CancellationToken token = tokenSource.Token;
    this.task = Task.Factory.StartNew(() => readData(token), token);

    this.tokenSource1 = new CancellationTokenSource();
    CancellationToken token1 = tokenSource1.Token;
    this.task1 = Task.Factory.StartNew(() => saveData(token1), token1);
}

private void stopTask()
{
    this.tokenSource.Cancel();            
    this.timerTask1.Stop();
    while (this.dataQueue.Count != 0)
    {
        System.Threading.Thread.Sleep(1000);
    }
    this.tokenSource1.Cancel();
    this.timerTask2.Stop();
    try
    {
        this.task.Wait();
        this.task1.Wait();
    }
    catch (Exception ex)
    {
        Debug.Print(ex.Message);
    }
    finally
    {
        this.tokenSource.Dispose();
        this.tokenSource1.Dispose();
        this.timerTask1.Dispose();
        this.timerTask2.Dispose();
        this.dataQueue.Clear();
    }
}

private void readData(CancellationToken token)
{            
    this.timerTask1 = new System.Timers.Timer();
    this.timerTask1.Interval = 20;
    this.timerTask1.Elapsed += new System.Timers.ElapsedEventHandler(this.timerTask1Elapsed);
    this.timerTask1.Start();

    if (token.IsCancellationRequested)
    {
        this.timerTask1.Stop();                
        this.timerTask1.Dispose();
    }
}

private void timerTask1Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Monitor.Enter(this.dataQueue);
    try
    {               
        this.dataQueue.Enqueue(readDataFromDevices());
    }
    finally
    {
        Monitor.Exit(this.dataQueue);
    }           
}

private void saveData(CancellationToken token)
{
    this.timerTask2 = new System.Timers.Timer();
    this.timerTask2.Interval = 3000;
    this.timerTask2.Elapsed += new System.Timers.ElapsedEventHandler(this.timerTask2Elapsed);
    this.timerTask2.Start();

    if (token.IsCancellationRequested)
    {
        this.timerTask2.Stop();
        this.timerTask2.Dispose();
    }
}

private void timerTask2Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    sb.Clear();

    Monitor.Enter(this.dataQueue);
    try
    {
        if (this.dataQueue.Count > 0)
        {
            for (int i = 0; i < this.dataQueue.Count; i++)
            {
                sb.AppendLine(this.dataQueue.Dequeue());
            }
            writeData(@"C:\", "TestWriteData.csv", sb);
        }
    }
    catch (Exception ex)
    {
        Debug.Print(ex.Message.ToString());
    }
    finally
    {
        Monitor.Exit(this.dataQueue);
    }

}

Моя проблема: после завершения запроса задачи былсработал, как лучше понять, когда очередь пуста и файл был записан на диск, и операции ввода-вывода были прекращены?

Кто-то может дать совет, как улучшить мой код, а затем исправить исключения иприложение заморожено?Спасибо всем заранее.

By, Jumpier

...