【问题标题】:How to use named Mutex如何使用命名互斥锁
【发布时间】:2017-09-24 00:23:38
【问题描述】:

我正在尝试使用 Mutex 来处理不同的进程/应用程序以写入同一个文件。

这是我的代码

 ILogTest logTest = new LogTest(new FileLog());
 logTest.PerformanceTest();


    public class ILogTest
    {
            public void PerformanceTest()
            {
                for (int i = 0; i < this.numberOfIterations; i++)
                {
                    try
                    {
                        Thread threadC = Thread.CurrentThread;
                        threadC = new Thread(ThreadProc);
                        threadC.Name = i.ToString();
                        threadC.Start();
                        threadC.Suspend();
                        threadC.IsBackground = true;
                    }
                    catch (Exception)
                    {
                        throw new Exception("errore");
                    }
                }
            }

            private void ThreadProc()
            {
                try
                {
                    log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
                    this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
                    this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
                    this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
                }
                catch (Exception)
                {
                    throw new Exception("errore");
                }
            }
    }

FileLog 是 ILogTest 的一个实现。

写法:

public void Write(string message)
    {
        try
        {
            rwl.WaitOne();
            try
            {
                string tID = Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.CurrentCulture);

                sw.WriteLine(sev.ToString() + "\t" + DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss", CultureInfo.CurrentCulture) + "\t\t"  + System.Reflection.Assembly.GetCallingAssembly().GetName().Name + "\t" + Process.GetCurrentProcess().Id.ToString(CultureInfo.CurrentCulture) + "\t" + tID + " \t " + message);


                sw.WriteLine("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
            }
            catch (Exception ex)
            {
                throw new ArgumentException("Cannot write to file " + ex.Message);
            }
            finally
            {
                rwl.ReleaseMutex();
            }
        }
        catch (ApplicationException)
        {
        }
    }

文件日志主要:

public FileLog()
    {
        try
        {
            rwl.WaitOne();
            string filePath = Path.GetTempPath() + "Test.txt";
            if (!File.Exists(filePath))
            {
                swa = new FileStream(filePath, FileMode.Append, FileAccess.Write);
                sw = new StreamWriter(swa);
            }
        }
        catch (Exception ex)
        {
            throw new ArgumentException("Cannot open or create file " + ex.Message);
        }

        try
        {
            if (sw == null)
            {
                swa = new FileStream(filePath, FileMode.Append, FileAccess.Write);
                sw = new StreamWriter(swa);
            }

            sw.AutoFlush = true;
        }
        catch (Exception ex)
        {
            throw new ArgumentException("Cannot write to file " + ex.Message);
        }
    }

尝试模拟它,它不会将任何内容写入文件,只会创建它.. 我不知道为什么。 有人可以帮我吗?谢谢

【问题讨论】:

  • 文件锁定不是更好吗? msdn.microsoft.com/en-us/library/…
  • @AdamBenson 这将需要所有其他尝试同时写入的线程/进程来捕获和处理文件当前锁定时引发的IOException。取决于可能并不理想的争论。
  • 考虑使用 log4net 的 FileAppender 和 InterProcessLock 锁定模型。如果没有必要,不要重新发明轮子。 (你至少可以使用their implementation 看看它是怎么做到的。)
  • @Christian - 嗯,没有意识到 C# 的实现是如此糟糕。自从我在 C++ 中使用文件锁定已经有一段时间了,但我绝对记得能够等待文件锁定(我记得那是因为我死锁了整个电视台并用糟糕的文件锁定将它们停播......) LockFileEx( Win32 API)会等待,如果你要求它:aljensencprogramming.wordpress.com/2015/05/06/…

标签: c# .net multithreading mutex streamwriter


【解决方案1】:

FileLog 构造函数调用 rwl.WaitOne() 获取互斥锁(我假设 rwlMutex 对象),但从不调用 rwl.ReleaseMutex()

因此,每个调用Write() 的线程都会阻塞它对rwl.WaitOne() 的调用,因为互斥锁仍归另一个线程所有。

您需要在FileLog 构造函数中释放Mutex,以便其他线程可以获取它。

另外,您可以在PerformanceTest 中致电threadC.Suspend();;除非有代码可以恢复线程,否则它们永远不会完成运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多