我使用
调用服务方法
ThreadPool.QueueUserWorkItem(o => service.Method(arg1, arg2));
服务有对象'loggingService',我使用的是Spring.Net
private readonly ILoggingService loggingService = ObjectBuilder.GetObjectByName("LoggingService");
'LoggingService'类是单例。它将日志信息写入log.txt。
当我尝试在此服务方法中调用loggingService.Info(“test”)时,我得到异常:文件正忙于另一个进程。
如何访问loggingService?
答案 0 :(得分:1)
你的单身人士显然是每个线程
您将需要某种方式在线程之间传递LoggingService
。
例如,您可以在原始帖子中设置service.loggingService
。
或者,您可以配置Spring.Net以使其成为非线程本地单例。
请注意,您的LoggingService必须是线程安全的,否则您将在运行时遇到奇怪的错误。
答案 1 :(得分:0)
在编写一些使用大量线程的客户端应用程序时,我遇到了类似的问题。
基本上,您希望LoggingService保留一个内部队列(其访问权限应通过锁控制),每次调用log方法时,只需将消息附加到此队列。在log方法结束时检查队列当前是否正在写入文件,如果没有,则开始写入。
答案 2 :(得分:0)
public static class SingletonLoggingService
{
public static ILoggingService LoggingService = ObjectBuilder.GetObjectByName("LoggingService");
}
SingletonLoggingService.LoggingService.Info("Test");
答案 3 :(得分:0)
我做到了!
我使用队列和线程:
internal class LoggingService : ILoggingService {
private readonly Queue<LogEntry> queue = new Queue<LogEntry>();
private Thread waiter;
public LoggingService() {
waiter = new Thread(AddLogEntry);
waiter.Start();
}
public void Shutdown() {
try {
waiter.Abort();
} catch {}
}
public void Error(string s, Exception e) {
lock (queue) {
queue.Enqueue(new LogEntry(s, e, LogEntryType.Error));
}
}
public void Warning(string message) {
lock (queue) {
queue.Enqueue(new LogEntry(message, LogEntryType.Warning));
}
}
public void Info(string message) {
lock (queue) {
queue.Enqueue(new LogEntry(message, LogEntryType.Info));
}
}
private void AddLogEntry(object state) {
while (true) {
lock (queue) {
if (queue.Count > 0) {
LogEntry logEntry = queue.Dequeue();
switch (logEntry.Type)
{
case LogEntryType.Error:
logWriter.Error(logEntry.Message, logEntry.Exception);
break;
case LogEntryType.Warning:
logWriter.Warning(logEntry.Message);
break;
case LogEntryType.Info:
logWriter.Info(logEntry.Message);
break;
}
}
}
Thread.Sleep(100);
if (waiter.ThreadState == ThreadState.Aborted) {
waiter = null;
break;
}
}
}
}
我在app结束时调用Shutdown():
protected override void OnExit(ExitEventArgs e) {
loggingService.Shutdown();
base.OnExit(e);
}