C# запуск процесса после завершения другого процесса

Один файл запускает 2 процесса одновременно. Оба процесса открывают один и тот же файл (первый пишет в файл, второй читает из файла).

Вопрос, как сделать так, чтобы сначала начинал работать 1й процесс , писал в файл, потом начинал работать 2й процесс и читал из файла? Важно, чтобы они запускались одновременно, 2й процесс должен дожидаться конца 1го процесса и только после этого запускаться.

Находил информацию про именованные мьютексы, однако минус в том, что первым начать работу может любой из процессов.

public static void  start1()
{
    Process mYproces = new Process();
    mYproces.StartInfo.FileName = @"C:\Users\mark\source\repos\file1\file1\bin\Debug\netcoreapp3.1\file1.exe";
    mYproces.Start();
    mYproces.WaitForExit();

}

public static void start2()
{
    Process mYproces = new Process();
    mYproces.StartInfo.FileName = @"C:\Users\mark\source\repos\file2\file2\bin\Debug\netcoreapp3.1\file2.exe";
    mYproces.Start();
    mYproces.WaitForExit();
    //mYproces.Kill();
}

static void Main(string[] args)
{
    var thread1 = new Thread(() => start1());
    var thread2 = new Thread(() => start2());
    thread1.Start();
    thread2.Start();
    thread1.Join();
    thread2.Join();
}

Первый exe файл

public static void d1() {
    Console.WriteLine("d1 start");
    StreamWriter f = new StreamWriter(@"C:\Users\mark\Downloads\MYTXT.txt", true);
    f.WriteLine("Строка d1");
    Thread.Sleep(2000);
    f.Close();
    Console.WriteLine("d1 end");
}

static void Main(string[] args)
{
    d1();
}

второй exe

public static void d2()
{
    Console.WriteLine("d2 start");
    StreamReader sr = new StreamReader(@"C:\Users\mark\Downloads\MYTXT.txt");
    string check = sr.ReadToEnd();
    Thread.Sleep(1);
    Console.WriteLine("d2 end");
}

static void Main(string[] args)
{
    d2();
}

P.S. Добавил именные мьютексы, однако возникает ошибка когда доходит до ReleaseMutex (Unhandled exception. System.ApplicationException: Object synchronization method was called from an unsynchronized block of code. at System.Threading.Mutex.ReleaseMutex())

1 приложение

 public static void d1() {
        StreamWriter f = new StreamWriter(@"C:\Users\mark\Downloads\MYTXT.txt", true);
        Console.WriteLine("d1 start");
        f.WriteLine("Строка d1");
        f.Close();
        Console.WriteLine("d1 end")
    }


    static void Main(string[] args)
    {

        d1();
        Thread.Sleep(100);
        Mutex.OpenExisting("MYMUTEX").ReleaseMutex();
    }

2 приложение

public static void d2()
    {

        Mutex.OpenExisting("MYMUTEX").WaitOne();
        Console.WriteLine("d2 start");
        StreamReader sr = new StreamReader(@"C:\Users\mark\Downloads\MYTXT.txt");
        string check = sr.ReadToEnd();
        Thread.Sleep(1);
        Console.WriteLine("d2 end");


    }
    static void Main(string[] args)
    {
        d2();
    }

в основном приложение добавил только Mutex mut = new Mutex(true, "MYMUTEX");


Ответы (1 шт):

Автор решения: aepot

Object synchronization method was called from an unsynchronized block of code. означает что вы пытаетесь зарелизить Mutex, установленный в другом потоке, не синхронизированном с текущим. Другими словами, если один поток занял мьютекс, то только он его может освободить, но ждать этого освобождения можно в любом потоке.

Вот пример блокировки с одним Mutex и двумя одновременно страртующими процессами. Пример сделал на базе одного и того же приложения с разными аргументами запуска.

static void Main(string[] args)
{
    if (args.Length > 0)
    {
        switch (args[0])
        {
            case "process1":
                Console.WriteLine("Process 1 started");
                Thread.Sleep(2000); // какая-то работа
                Console.WriteLine("Process 1 finished");
                break;
            case "process2":
                Mutex.OpenExisting("MyMutex").WaitOne(); // ждем, пока нас отпустят
                Console.WriteLine("Process 2 started");
                Thread.Sleep(2000); // какая-то работа
                Console.WriteLine("Process 2 finished");
                break;
        }
    }
    else
    {
        Mutex mutex = new Mutex(false, "MyMutex");
        mutex.WaitOne(); // сажаем на цепь второй процесс
        Console.WriteLine("Main process started");

        // пусть к самому себе для .NET Core 3.1, как я понял, это он у вас
        string path = Process.GetCurrentProcess().MainModule.FileName;

        Process process1 = new Process();
        process1.StartInfo.FileName = path;
        process1.StartInfo.Arguments = "process1";
        // можно сделать так, чтобы процесс стартовал в отдельном окне
        // process1.StartInfo.UseShellExecute = true;

        Process process2 = new Process();
        process2.StartInfo.FileName = path;
        process2.StartInfo.Arguments = "process2";
        // process2.StartInfo.UseShellExecute = true;

        process1.Start();
        process2.Start();
        // оба дочерних процесса запущены, все по правилам

        process1.WaitForExit();
        mutex.ReleaseMutex(); // отпускаем второй процесс
        process2.WaitForExit();
        Console.WriteLine("Main process finished");
        Console.ReadKey();
    }
}

Потоки Thread вам здесь не нужны, совсем.

Main process started
Process 1 started
Process 1 finished
Process 2 started
Process 2 finished
Main process finished
→ Ссылка