У меня запущена простая программа регистрации производителя-потребителя, которая использует объект BlockingCollection в качестве буфера.
Я использую getconsumingenumerable () в цикле foreach для записи данных.
Я пытаюсь исключить сценарий, в котором вышеприведенный цикл 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;
}
}
}