我想知道我是否正确/有效地使用了这些组件。特别写入文件我不确定是否是线程安全的,虽然它没有在这个测试项目中抛出任何错误(即使没有睡眠)。我不知道这是不是因为广播公司已经同步,因此文件写入也随后同步......?
我不确定我是否可以使用普通的List<>或其他一些集合而不是BlockingCollection<>对于m_listeners
。我可以在执行开始时干净地添加听众,但我想如果我想稍后删除它们,我就限制了自己。例如,我可能想要在未来更动态地添加/删除侦听器,例如在显示子表单时添加TextBox侦听器并在关闭时删除它。
WindowsFormsApplication1包含:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
//Fields
private volatile bool cancel1 = false;
private volatile bool cancel2 = false;
private volatile bool cancel3 = false;
private volatile bool cancel4 = false;
public Form1()
{
InitializeComponent();
}
//Event Handlers
private void button1_Click(object sender, EventArgs e)
{
//Automated Producers
if (!cancel1)
{
Task.Factory.StartNew(() =>
{
int count = 0;
while (!cancel1)
{
Log.Append("File", "log to file " + count++);
Thread.Sleep(1);
}
cancel1 = false;
});
}
if (!cancel2)
{
Task.Factory.StartNew(() =>
{
int count = 0;
while (!cancel2)
{
Log.Append("GUI", "log to GUI " + count++);
Thread.Sleep(2);
}
cancel2 = false;
});
}
if (!cancel3)
{
Task.Factory.StartNew(() =>
{
int count = 0;
while (!cancel3)
{
Log.Append("Error", "log to Error " + count++);
Thread.Sleep(3);
}
cancel3 = false;
});
}
if (!cancel4)
{
Task.Factory.StartNew(() =>
{
int count = 0;
while (!cancel4)
{
Log.Append("", "log to console " + count++);
Thread.Sleep(4);
}
cancel4 = false;
});
}
}
private void button2_Click(object sender, EventArgs e)
{
//Cancel Producers
cancel1 = true;
cancel2 = true;
cancel3 = true;
cancel4 = true;
}
private void Form1_Load(object sender, EventArgs e)
{
//Delete Old Files
string LogFile = Directory.GetCurrentDirectory() + "\\Log.txt";
if (File.Exists(LogFile))
File.Delete(LogFile);
string VerboseLog = Directory.GetCurrentDirectory() + "\\VerboseLog.txt";
if (File.Exists(VerboseLog))
File.Delete(VerboseLog);
//Add Consumer Callback methods to Logger class
//Append to File
Log.RegisterWriter(
new Action<string, string>((tag, entry) =>
{
if (tag == "File")
{
using (TextWriter Stream = new StreamWriter(LogFile, true))
{
Stream.WriteLine(entry);
}
}
}));
//Append to different file
Log.RegisterWriter(
new Action<string, string>((tag, entry) =>
{
using (TextWriter Stream = new StreamWriter(VerboseLog, true))
{
Stream.WriteLine(DateTime.Now + ":\t" + entry);
}
}));
//Append to Console
Log.RegisterWriter(
new Action<string, string>((tag, entry) =>
{
Console.WriteLine(entry);
}));
//Append to multiline textBox1
Log.RegisterWriter(
new Action<string, string>((tag, entry) =>
{
if (tag == "GUI")
{
entry += "\r\n";
if (this.InvokeRequired)
{
this.BeginInvoke(new Action<string>(textBox1.AppendText), new object[] { entry });
return;
}
else
{
//Under the circumstances, this never occurs. An invoke is always required.
textBox1.AppendText(entry);
return;
}
}
}));
}
}
public static class Log
{
//Fields
private static BlockingCollection<Tuple<string, string>> m_logItems;
private static BlockingCollection<Action<string, string>> m_listeners;
//Methods
public static void Append(string p_tag, string p_text)
{
//Add Log Entry
m_logItems.Add(new Tuple<string, string>(p_tag, p_text));
}
public static void RegisterWriter(Action<string, string> p_callback)
{
//Add callback method to list
m_listeners.Add(p_callback);
}
//Constructor
static Log()
{
//Init Blocking Lists
m_listeners = new BlockingCollection<Action<string, string>>();
m_logItems = new BlockingCollection<Tuple<string, string>>();
//Begin Log Entry Consumer Task
Task.Factory.StartNew(() =>
{
//Consume as Log Entries are added to the collection
foreach (var logentry in m_logItems.GetConsumingEnumerable())
{
//Broadcast to each listener
foreach (var callback in m_listeners)
{
callback(logentry.Item1, logentry.Item2);
}
}
});
}
}
}
我不想使用第三方日志库(部分地更好地理解这些机制)并且只是想创建一种非常简单的方法来将项目从我的代码(任何线程)中的任何地方发布到各种输出(文件,文本框,控制台等)。
实际应用程序中的登录频率远远低于此处所示(即它应该永远不会产生超过现实条件下可以消耗的频率)。