Как получить доступ к "extern" методу из двух разных потоков? - PullRequest
0 голосов
/ 27 сентября 2019

Я работаю над основным веб-приложением .Net, которое использует P / Invoke для доступа к библиотекам C ++ для получения информации.Мой сбой приложения, когда пользовательская функция триггера «Тест».

Предполагается:

  1. Класс Util былзарегистрирован как «Синглтон» в StartUp.cs
  2. Функция таймера запуска была запущена до вызова пользователя «Тест»
  3. Все IntPtr одинаковы
  4. _subject используется для SIGNALRпотоковая передача.

NativeLib.cs

public class static NativeLib () {
        [DllImport("abc.so", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern void MethodA (IntPtr ptrKey, [MarshalAs(UnmanagedType.LPStr)] string requestMessage, [MarshalAs(UnmanagedType.LPStr)] ref string responseMessage);

        [DllImport("abc.so", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern void MethodB (IntPtr ptrKey, [MarshalAs(UnmanagedType.LPStr)] string requestMessage, [MarshalAs(UnmanagedType.LPStr)] ref string responseMessage);
}

HomeController.cs

public class TestController : Controller {

   public IActionResult Test () {
    IntPtr ptr = 123456789;
    string request = "xxxxx";
    string response = "";
    NativeLib.MethodB(ptr, request, ref response);

    // Do something
    }
}

Util.cs

public class Util {
private readonly SemaphoreSlim _lock= new SemaphoreSlim(1, 1);
private readonly Subject<string> _subject = new Subject<string>();

public async Task StartTimer () {
     private readonly TimeSpan _updateInterval = TimeSpan.FromMilliseconds(1000);
     timer = new Timer(UpdateMessage, null, _updateInterval, _updateInterval);
}

public async Task UpdateMessage () {
     await _lock.WaitAsync();
     try {
         IntPtr = 123456789;
         string request = "xxxxx";
         string response = "";
         NativeLib.MethodB(ptr, request, response);
         _subject.OnNext(response);
     }
     finally
     {
        _lock.Release();
     }
}
}

==============================================

C ++

Main.cpp

void MethodA(T* object, char* request ,char** response) {
  // Accessing memory-mapped file with object pointer
  // return value A
}

void MethodB (T* object, char* request ,char** response) {
  // Accessing memory-mapped file with object pointer
  // return value B
}
...