我有以下代码设置
public interface ILogger
{
void WriteData(string Data);
}
public class Logger : ILogger
{
public void WriteData(string Data)
{
//Write to disk
}
}
public interface ILogic
{
void ProcessData(string Data);
}
public class Logic : ILogic
{
private ILogger Logger;
public Logic(ILogger Logger)
{
this.Logger = Logger;
}
public void ProcessData(string Data)
{
//Do stuff
Logger.WriteData("Data to write");
}
}
public class MainEntryPointClass
{
private BlockingCollection<string> DataInCollection;
private Task DataInTask;
private CancellationTokenSource CancellationTokenSource;
public Start()
{
InitializeDataIn();
}
private void InitializeDataIn()
{
CancellationTokenSource = new CancellationTokenSource();
DataInCollection = new BlockingCollection<DataInContents>();
DataInTask = Task.Factory.StartNew(() => ProcessDataIn(CancellationTokenSource.Token));
}
private void ProcessDataIn(CancellationToken CancelToken)
{
while (!CancelToken.IsCancellationRequested)
{
foreach (var item in DataInCollection.GetConsumingEnumerable())
{
Logic.ProcessData(item);
}
}
}
}
所以我在我的主类中创建了一个新的Task,然后将数据添加到DataInCollection中以便在数据进入时对其进行排队,我们每隔30ms左右就会进行一次谈话。这成功处理。
我现在想在一个单独的线程上将数据写入文件,这样如果存在磁盘问题,主逻辑检查就不会受到影响。如果存在磁盘问题,则逻辑可以继续。我只是不确定我在单独的线程上写文件的位置?它是在Main类,Logic类还是Logger类中?
答案 0 :(得分:3)
Logger
有责任确保它不会阻止来电者。它可以使用许多不同的策略。您不希望将这些策略烘焙到使用它的类中。
我将消息排入BlockingCollection<T>
,然后让一个IO线程将其写入磁盘。
我还建议模仿现有的日志记录界面,例如Common.Logging's ILog
,这样如果您的“无第三方”要求被解除,您就可以轻松切换到现有的日志记录框架。
类似的东西:
class AsyncLogger:ILogger
{
public AsyncLogger(ILogger backingLogger)
{
new Thread(()=>
{
while(true)
{
var data=_queue.Take();
_backingLogger.WriteData(data);
}
}
).Start();
}
public void WriteData(string data)
{
_queue.Enqueue(data);
}
}
(我省略了诸如IO线程的终止条件,字段,多个记录器的处理,......)
答案 1 :(得分:1)
Logger类有望负责日志记录。所以它似乎是将传入数据记录到磁盘的正确位置。