过去我做过类似的事情
private static bool AlreadyRunning()
{
var processes = Process.GetProcesses();
var currentProc = Process.GetCurrentProcess();
logger.Info($"Current proccess: {currentProc.ProcessName}");
foreach (var process in processes)
{
if (currentProc.ProcessName == process.ProcessName && currentProc.Id != process.Id)
{
logger.Info($"Another instance of this process is already running: {process.Id}");
return true;
}
}
return false;
}
哪个效果很好。在新的dotnet核心世界中,所有内容的进程名称都为dotnet
,因此我一次只能运行一个dotnet
个应用程序!不是我想要的:D
有没有理想的方式在dotnet中这样做?我看到mutex建议,但我不确定我是否理解在Windows机器以外的其他系统上运行的可能的缺点或错误状态。
答案 0 :(得分:3)
.NET Core现在支持全局命名的互斥锁。来自PR description,添加了该功能:
- 在支持线程进程共享的强大递归互斥锁的系统上,将使用它们
- 在其他系统上,使用文件锁。遗憾的是,文件锁在阻塞等待调用中没有超时,我没有找到任何其他具有必要属性的定时等待的同步对象,因此轮询是为了定时等待。
另外,Named mutex not supported on Unix问题中有一个关于互斥名称的有用说明,应该使用:
默认情况下,名称具有会话范围,并且会话在Unix上更精细(每个终端都有自己的会话)。尝试添加" Global"名称的前缀减去引号。
答案 1 :(得分:0)
最后我使用了一个互斥锁,看起来没问题。
我从这里抓起代码 What is a good pattern for using a Global Mutex in C#?
我正在使用的核心版本似乎没有一些安全设置,所以我只是删除它。我相信一切都会好的。 (new Mutex
只需要3个参数)
private static void Main(string[] args)
{
LogManager.Configuration = new XmlLoggingConfiguration("nlog.config");
logger = LogManager.GetLogger("console");
logger.Info("Trying to start");
const string mutexId = @"Global\{{guid-guid-guid-guid-guid}}";
bool createdNew;
using (var mutex = new Mutex(false, mutexId, out createdNew))
{
var hasHandle = false;
try
{
try
{
hasHandle = mutex.WaitOne(5000, false);
if (!hasHandle)
{
logger.Error("Timeout waiting for exclusive access");
throw new TimeoutException("Timeout waiting for exclusive access");
}
}
catch (AbandonedMutexException)
{
hasHandle = true;
}
// Perform your work here.
PerformWorkHere();
}
finally
{
if (hasHandle)
{
mutex.ReleaseMutex();
}
}
}
}