从另一个线程访问单例对象

发布于 2024-08-15 16:10:58 字数 414 浏览 8 评论 0原文

调用服务方法

我使用ThreadPool.QueueUserWorkItem(o => service.Method(arg1, arg2));

服务有对象“loggingService”,我使用 Spring.Net

私有只读 ILoggingServiceloggingService = ObjectBuilder.GetObjectByName("LoggingService");

'LoggingService' 类是单例的。它将日志信息写入log.txt。

当我尝试在此服务方法中调用loggingService.Info(“test”)时,出现异常:文件正被另一个进程占用。

如何访问loggingService?

I call service method using


ThreadPool.QueueUserWorkItem(o => service.Method(arg1, arg2));

Service has object 'loggingService' with I was get using Spring.Net


private readonly ILoggingService loggingService = ObjectBuilder.GetObjectByName("LoggingService");

'LoggingService' class is singleton. It writes log info to log.txt.

When I try to call loggingService.Info("test") in this service method, I get exception: file is busy by another process.

How can I access to the loggingService?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

好听的两个字的网名 2024-08-22 16:10:58

您的单例显然是每个线程的。
您将需要某种跨线程传递 LoggingService 的方法。

例如,您可以在原始线程中设置service.loggingService

或者,您可以配置 Spring.Net 以使其成为非线程本地单例。

请注意,您的 LoggingService 必须是线程安全的,否则您会在运行时遇到奇怪的错误。

Your singleton is apparently per-thread.
You will need some way of passing the LoggingService across threads.

For example, you could set service.loggingService in the original thread.

Alternatively, you might be able to configure Spring.Net to make it a non-thread-local singleton.

Note that your LoggingService must be thread-safe, or you'll get strange errors at runtime.

软的没边 2024-08-22 16:10:58

我在编写一些使用一堆线程的客户端应用程序时遇到了类似的问题。

基本上,您希望 LoggingService 保留一个内部队列(其访问应通过锁控制),并且每次调用 log 方法时,您只需将消息附加到该队列中。在 log 方法结束时检查队列当前是否正在写入文件,如果没有,则开始写入。

I had a similar issue while writing some client side application that used a bunch of threads.

Basically you want your LoggingService to keep an internal queue (whose access should be controlled via a lock) and every time you call the log method you only append the message to this queue. At the end of the log method check if the queue is currently being written to a file and if not, start writing.

萌无敌 2024-08-22 16:10:58
public static class SingletonLoggingService
{
    public static ILoggingService LoggingService = ObjectBuilder.GetObjectByName("LoggingService"); 
}


SingletonLoggingService.LoggingService.Info("Test");
public static class SingletonLoggingService
{
    public static ILoggingService LoggingService = ObjectBuilder.GetObjectByName("LoggingService"); 
}


SingletonLoggingService.LoggingService.Info("Test");
沧桑㈠ 2024-08-22 16:10:58

我做到了!

我使用队列和线程:

    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;
            }
        }
    }
}

我在应用程序末尾调用 Shutdown() :

        protected override void OnExit(ExitEventArgs e) {
        loggingService.Shutdown();
        base.OnExit(e);
    }

I did it!

I use Queue and threading:

    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;
            }
        }
    }
}

I call Shutdown() at the end of app:

        protected override void OnExit(ExitEventArgs e) {
        loggingService.Shutdown();
        base.OnExit(e);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文