我正在编写简单的日志框架,用户可以逐行或批量记录。User Write(message) 在他的代码和基于 bool flushEveryLine (每行为 true,批量写入为 false),通过调用 flush() 方法写入日志。消息在主线程上创建,当写入文件时,outputConsole 或 DebugConsole 使用 Task 在不同的线程上。List 是我想使用 TPL 在主线程和工作线程之间同步的内容。所以当 TimerEvent 发生时,丢失的消息应该被写入输出。问题是消息更改请参阅下面的消息。
protected virtual void Write(LogMessage message)
{
if (!this.IsEnabled) // log enabled or disabled.
return;
List<Task> list = new List<Task>();
foreach (Task task in _taskList)
{
if (task.Status != TaskStatus.RanToCompletion)
list.Add(task);
}
_taskList = list;
Task.WaitAll(_taskList.ToArray());
lock(storage)
{
//Add message to messages
**this.messages.Add(message);**
if (FlushEveryLine)
**Flush();**
}
public void Flush()
{
if (messages.Count == 0)
return;
_taskToMessagesMap.Add(counter, this.messages);
**Task.Factory.StartNew(() => FlushData(counter));**
++counter;
if (counter > 30000) // reset counter after large increment.
{
counter = 0;
}
this.messages.Clear();// clear the messages to record new set of messages before writing.
}
protected virtual void FlushData(int index)
{
**List<LogMessage> messages = _taskToMessagesMap[index];**
if (!IsEnabled) // logs enabled or not.
{
return;
}
lock (messages)
{
if (messages.Count == 0)
{
return;
}
IEnumerable<LogMessage> temp = messages.OrderBy(msg => msg.TimeStamp).ToArray();
this.flush(temp);
}
return;
}
代码说明::_taskToMessagesMap = new Dictionary(); // 存储计数器和消息列表的字典。这是 hack,因为我想测试 List 的行为。
Task.Factory.StartNew(() => FlushData(counter)); //实际上我想为每个线程使用 Flush(messages) 以便在调用 FlushData() 时应该使用传递的消息。但是我在执行工作线程时看到它使用当前消息列表。我知道列表是通过引用传递的,因此看到了这种行为,但我在上面的例子中也看到了整数的这种行为。示例:我的字典只有一个键 {0} 和所有测试消息,但是当它进入工作线程时,它会查找键 1。为什么?整数参数应按值传递。创建工作线程时,我将 0 作为参数传递。我怎样才能解决这个问题。
请帮忙,因为我被卡住了。