如何在有故障的线程上重新启动进程?

时间:2019-06-21 22:09:33

标签: c# task-parallel-library blockingcollection

我运行了一个简单的生产者-消费者日志记录程序,该程序使用BlockingCollection对象作为缓冲区。 我在一个foreach循环中使用geturingenumerable()来写入数据。

我正在尝试解决上面的foreach循环可能中断的情况。在那种情况下,我要刷新并关闭文件并重新启动使用者线程。

我是多线程范例的新手,我不确定是否能正确解决上述问题。我只是做错了吗?

非常感谢您的帮助。

/// <summary>
/// Task that will write the logs
/// </summary>
private static Task loggerTask;

/// <summary>
/// Counter to flush data after every 100 foreach iterations in the getconsumingEnumerable method
/// </summary>
private static int Ticker
        {
            get
            {
                return _ticker;
            }
            set
            {
                _ticker = value;
                if (_ticker > 99)
                {
                    //flush buffer
                    _tWriter.WriteLine("---Flush---");
                    _tWriter.Flush();
                    //Check if the day has changed
                    if (string.Compare(_fileName, "log_" + DateTime.Today.Date.ToString("yyyy_MM_dd") + ".txt") > 0)
                    {
                        //close connection to the old file
                        _tWriter.Close();
                        _tWriter.Dispose();

                        // re initialize it with a new file
                        InitializeMyWriter();
                    }
                    //reset ticker
                    _ticker = 0;
                }
            }
        }



        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static Task GetMainLogProcess()
        {
            return Task.Factory
                .StartNew(() => { WriteLog(); })
                .ContinueWith(tsk =>
                {
                    using (StreamWriter sw = File.AppendText(GetPath() + "LOGGERKaLOG.txt"))
                    using (TextWriter tw = TextWriter.Synchronized(sw))
                    {
                        tw.WriteLine("<-------------------START------------------->");
                        tw.WriteLine(string.Format("[{0}] : Logger exception!!", DateTime.Now.ToLongDateString()));
                        tw.WriteLine(string.Format("[{0}] : {1}", DateTime.Now.ToLongDateString(), tsk.Exception.Message));
                        tw.WriteLine(string.Format("[{0}] : {1}", DateTime.Now.ToLongDateString(), tsk.Exception.Flatten()));
                        tw.WriteLine("<-------------------END------------------->");

                    }
                    loggerTask = GetMainLogProcess();
                }, TaskContinuationOptions.OnlyOnFaulted);
        }

//class Constr
        static Logger()
        {
            //initialize the queue
            _queue = new BlockingCollection<string[]>();

            //start a thread to process items from the queue.
            loggerTask = GetMainLogProcess();
        }


/// <summary>
        /// Writes writables to file.
        /// </summary>
        private static void WriteLog()
        {
            //just write
            foreach (string[] writables in _queue.GetConsumingEnumerable())
            {
                try
                {
                    //check if the underlying stream writers are there. If not re initialize them
                    if (_sWriter == null || _sWriter.BaseStream == null)
                    {
                        InitializeMyWriter();
                    }


                    _tWriter.WriteLine("<---------------------------START--------------------------->");
                    _tWriter.WriteLine("Time: " + DateTime.Now.ToLongTimeString());
                    foreach (string writable in writables)
                    {
                        _tWriter.WriteLine(writable);
                    }

                    _tWriter.WriteLine("<---------------------------END--------------------------->");
                    throw new Exception("Ha Ha.");
                    //increment the counter by 1
                    Ticker++;
                }
                catch (ObjectDisposedException ode)//if the stream writer of text writer was disposed bu a write was attempted
                {
                    InitializeMyWriter();
                    //retry to write the missed data
                    _tWriter.WriteLine("<---------------------------START--------------------------->");
                    _tWriter.WriteLine("Time: " + DateTime.Now.ToLongTimeString());
                    foreach (string writable in writables)
                    {
                        _tWriter.WriteLine(writable);
                    }

                    _tWriter.WriteLine("<---------------------------END--------------------------->");
                }
                catch
                {
                    throw;
                }

            }
        }

0 个答案:

没有答案