首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >单实例.NET核心应用程序(或使crontab只运行我的应用程序的一个实例)

单实例.NET核心应用程序(或使crontab只运行我的应用程序的一个实例)
EN

Stack Overflow用户
提问于 2017-10-29 21:44:03
回答 4查看 3.2K关注 0票数 5

我想在Linux中使用.NET crontab在调度上执行核心应用程序。这是一个长时间运行的操作,如果以前的执行还没有完成,我不希望运行另一个实例。换句话说,我不希望crontab在给定时间执行多个.NET核心应用程序实例。

有什么办法可以避免吗?我宁愿不修改我的应用程序的代码。也许crontab有一个避免并发的选项。我不是Linux专家(目前) :)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-11-01 10:43:41

我终于使用了一个适用于Raspbian的小工具:flock

在我的crontab配置文件中,我放置了以下内容:

代码语言:javascript
运行
复制
flock -n /tmp/importer.lock dotnet ~/Desktop/Importer/Plugin.Clm.Importer.Console.dll

看起来,flock在运行时写入一个锁文件,并执行命令。它再次被执行,锁文件在那里,它只是失败了。当它完成时,它释放文件,允许再次调用它。

用几句话来说:它充当一个信号量:)

票数 2
EN

Stack Overflow用户

发布于 2018-05-04 10:33:01

对于那些想从代码中检查实例的人,您可以使用下面这样的命名互斥

代码语言:javascript
运行
复制
const string mutexName = @"Global\appName";

var mutex = new Mutex(true, mutexName, out var createdNew);

if (!createdNew)
{
    Console.WriteLine(mutexName + " is already running! Exiting the application.");
    return;
}

确保您的互斥名以"Global\"开头。

票数 9
EN

Stack Overflow用户

发布于 2017-10-31 07:08:51

如果您想在程序中解决它,您可以循环遍历System.Diagnostics.Process.GetProcesses中的所有进程,并检查是否有任何进程可执行路径以您的文件名结束。

代码语言:javascript
运行
复制
[System.STAThread]
static void Main(string[] args)
{
    foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
    {
        if (p.MainModule.FileName.EndsWith("bla.exe", System.StringComparison.CurrentCultureIgnoreCase))
            return;
    }
    [...]
}

否则,让脚本在/var/run中设置一个值,并检查该文件是否存在。如果程序以任何方式退出,该文件将被删除。

此外,解决长时间运行。程序通常不应该花那么长时间。在我看来,你好像做错了什么,除非你确实在处理数千兆字节的数据。

如果MainModule返回dotnet,您还可以重新链接proc/pid/exe/ (Linux或BSD)或/proc/self/exe (仅用于linux)。

代码语言:javascript
运行
复制
   int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
   System.Text.StringBuilder sb = new System.Text.StringBuilder(System.Environment.SystemPageSize);
   int ret = Mono.Unix.Native.Syscall.readlink($"/proc/{pid}/exe", sb);
   string res = sb.ToString();
   System.Console.WriteLine(res);

或者,如果这也只产生dotnet,则可以读取命令行参数(/proc/pid/cmdline - linux ):

代码语言:javascript
运行
复制
public static byte[] ReadReallyAllBytes(string filename)
{
    byte[] retValue = null;

    using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
    {
        byte[] buffer = new byte[System.Environment.SystemPageSize];
        List<byte> byteList = new List<byte>();
        int ct = 0;
        while ((ct = fs.Read(buffer, 0, buffer.Length)) > 0)
        {
            for (int i = 0; i < ct; ++i)
            {
                byteList.Add(buffer[i]);
            }
        }

        buffer = null;
        retValue = byteList.ToArray();
        byteList.Clear();
        byteList = null;
    }

    return retValue;
}


public static List<string> GetCmdLineArgs(int pid)            
{
    List<string> ls = new List<string>();                

    byte[] buffer = ReadReallyAllBytes($"/proc/{pid}/cmdline");
    int last = 0;

    for (int i = 0; i < buffer.Length; ++i)
    {
        if (buffer[i] == 0)
        {
            string arg = System.Text.Encoding.UTF8.GetString(buffer, last, i-last);
            last = i + 1;
            ls.Add(arg);
        } // End if (buffer[i] == 0)

    } // Next i 

    // System.Console.WriteLine(ls);
    return ls;
}

现在,如果MainModule是dotnet,请检查命令行参数列表是否包含dll/exe。另外,如果您做了一个发行版构建(独立的-没有共享的框架),那么它应该与MainModule一起工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47005542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档