2016-12-23 2 views
0

У меня есть API-интерфейс, называемый Application Library. Внутри у меня есть метод SynchronizeMe.Проблема при синхронизации метода при вызове из другого приложения

public class APIClass 
    { 
     object baton = new object(); 
     static int count = 0; 
     public void SynchronizeMe() 
     { 
      while(true) 
      { 
       lock (baton) 
       { 
        int temp = count; 
        Thread.Sleep(5000); 
        count = temp + 1; 

        Console.WriteLine("Thread Id " + Thread.CurrentThread.ManagedThreadId + " Name:" + Thread.CurrentThread.Name + " incremented count to " + count); 
       } 
       Thread.Sleep(1000); 
      } 

     } 
    } 

У меня есть две консоли Application Thread1 и Thread2. Оба они вызывают метод SynchronizeMe. Как

API.APIClass apicall = new API.APIClass(); 
apicall.SynchronizeMe(); 

Когда я запускаю это я вижу, оба печать счета начинаются с 1. Это означает, что она не синхронизирована. Я понимаю концепцию многопоточности над чем-то неправильно? Или у кода есть проблема? Или Thread в том же приложении можно синхронизировать. Если я хочу синхронизировать этот путь, каков путь?

Я думаю, что и Thread1, и Thread2 имеют разный экземпляр APIClass, поэтому синхронизация невозможна. Есть ли выход?

+0

Чтобы уточнить, есть ли у вас два отдельно работающих консольных приложения, которые вызывают библиотеку, или два потока в одном консольном приложении? – user783836

+0

@ user783836 Два отдельно работающих консольных приложения. – TBAG

+0

@TBAG см. Мой ответ – user783836

ответ

2

В случае, когда у вас есть два отдельных консольных приложения, блокировки с использованием ключевого слова lock не используются между ними - lock является локальным для отдельного процесса.

Если вы хотите заблокировать процессы, вам нужно вместо этого использовать named mutex.

См. http://www.c-sharpcorner.com/UploadFile/1d42da/threading-with-mutex/.

Для перекрестного процесса блокировки с помощью мьютекса см http://mikeperetz.blogspot.co.uk/2013/12/cross-process-locking-using-named-mutex.html

Ваш код будет выглядеть примерно так:

public class APIClass 
{ 
    private const string MutexName = "FAA9569-7DFE-4D6D-874D-19123FB16CBC-8739827-[SystemSpecicString]"; 
    private Mutex _globalMutex; 
    private bool _owned = false; 
    private int timeToWait = 1000; 

    object baton = new object(); 
    static int count = 0; 
    public void SynchronizeMe() 
    { 
     _globalMutex = new Mutex(true, MutexName, out _owned); 
     while(true) 
     { 
      while (!_owned) 
      { 
       // did not get the mutex, wait for it. 
       _owned = _globalMutex.WaitOne(timeToWait); 
      } 

      int temp = count; 
      Thread.Sleep(5000); 
      count = temp + 1; 

      Console.WriteLine("Thread Id " + Thread.CurrentThread.ManagedThreadId + " Name:" + Thread.CurrentThread.Name + " incremented count to " + count); 
      // release the mutex 
      _globalMutex.ReleaseMutex(); 
      Thread.Sleep(1000); 
     } 

    } 
} 
+0

Пока синхронизация будет работать, она все равно не будет использовать одну и ту же переменную счетчика между процессами. – nvoigt

+0

@nvoigt справедливая точка и ее непонятная из OP, если это цель, или если это просто понимание кросс-процесса синхронизации – user783836

+0

@ user783836 вторая нить не может получить блокировку. Только thread1 является преимущественным значением. Вторая консоль ничего не дает. – TBAG

0

Два процесса (или, вернее, два приложения доменов) будет загружать два совершенно отдельные копии из вашей библиотеки.

Таким образом, ваш lock не только заблокирует копию вызывающей сборки, ваша переменная count будет существовать как две отдельные копии.

У вас может быть процессно-агностическая синхронизация, например, с mutex, но вам все равно нужно найти способ обмена этим счетчиком. Это может быть так же просто, как хранить его в записи файла или реестра, или вы можете использовать базу данных. Но если вы хотите сохранить его в памяти, вам нужно будет запустить третий процесс вместо загрузки копии каждой библиотеки в существующие процессы. Это означает, что вам понадобится inter process communication.

Смежные вопросы