我正在关注线程here这篇文章。在那部分下 Mutex下面的代码就在那里。
class OneAtATimePlease
{
static void Main()
{
// Naming a Mutex makes it available computer-wide. Use a name that's
// unique to your company and application (e.g., include your URL).
using (var mutex = new Mutex (false, "oreilly.com OneAtATimeDemo"))
{
// Wait a few seconds if contended, in case another instance
// of the program is still in the process of shutting down.
if (!mutex.WaitOne (TimeSpan.FromSeconds (3), false))
{
Console.WriteLine ("Another app instance is running. Bye!");
return;
}
RunProgram();
}
}
static void RunProgram()
{
Console.WriteLine ("Running. Press Enter to exit");
Console.ReadLine();
}
}
但是当我运行它时,代码没有按预期运行,如果我运行exe(上面生成的exe)两次,它应该打印“另一个应用程序实例正在运行。再见!” 。但它不会那么阻止。
但是,如果我删除了使用块,代码就会按预期正常运行。
请帮帮我。我是线程概念的新手。
更新
很抱歉误导。我实际上并没有像那篇文章中那样写。
我的代码原样,
internal class Program
{
/// <summary>
/// Entry point
/// </summary>
/// <param name="args">The arguments.</param>
internal static void Main(string[] args)
{
//Misc.RunAssemblies();
var threadingDemo = new ThreadingDemo();
threadingDemo.MutexDemo();
Console.ReadLine();
}
}
namespace LearnNet.Console
{
using System.Threading;
public class ThreadingDemo
{
public void MutexDemo()
{
using (var mutex = new Mutex(false, "Global\\oreilly.com OneAtATimeDemo"))
{
// Wait a few seconds if contended, in case another instance
// of the program is still in the process of shutting down.
if (!mutex.WaitOne(0, false))
{
System.Console.WriteLine("Another app instance is running. Bye!");
return;
}
RunProgram();
}
}
static void RunProgram()
{
System.Console.WriteLine("Running. Press Enter to exit");
}
}
}
这再现了我上面解释的问题。如果我删除使用块,它的行为正确。
答案 0 :(得分:1)
您必须了解互斥锁的工作原理。 WaitOne
获取它,ReleaseMutex
或弃置会释放它。在使用块结束时(当控制流离开它时),互斥量被处理(这就是为什么首先使用块的原因),因此被释放。在更新的代码中,获取互斥锁,然后在RunProgram
语句后立即释放,并且任何后续实例也会立即获取并释放它。
当您不使用阻止时,您不需要Dispose
互斥锁,因此不要释放互斥锁。当Console.ReadLine
语句执行时 - 进程仍然持有互斥锁。当您的流程结束时,互斥锁仍然会被释放,但这不是很好的做法 - 最好总是明确释放互斥锁。
至于为什么它在您发布的第一个代码(更新前)中工作 - Console.ReadLine()
语句在内部使用块,因此当此语句上的控制流阻塞时 - 进程仍然保留互斥锁。