Задача, с которой я сталкиваюсь, заключается в том, что я пишу службу WCF, которая по своей природе многопоточна для работы с библиотекой C, которую я знаю, не является потокобезопасной, и у меня нет возможности влияют на библиотеку, которую я звоню. Библиотека, которую я вызываю, имеет метод инициализации для настройки оборудования и установки обработчика обратного вызова.C# Force Unmanaged Resources To Be Released
Если я выполняю этот процесс в консольном приложении, он работает абсолютно нормально, поскольку он находится в одном потоке.
Чтобы преодолеть проблемы, я создал класс-помощник, который реализует IDisposable для настройки оборудования, совершает вызовы и, надеюсь, разорвется, как только он будет завершен.
Sample вспомогательный класс:
public class MyClass
{
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void Setup(ushort var_one, ushort var_two);
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int Initialise(int port_num, int short_timeout, int long_timeout,
TXN_CALLBACK callback);
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetDeviceStatus();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void TXN_CALLBACK(int size, [MarshalAs(UnmanagedType.LPStr)] string the_data);
private int Setup(ushort var_one, ushort var_two);
{
Setup(var_one, var_two);
int foo= Initialise(0, shorttimeout, longtimeout, txn_callback);
return foo;
}
public MyStruct GetStatus()
{
Setup(0, 0);
return PtrToStruct<MyStruct>(GetDeviceStatus());
}
private static void txn_callback(int size, string the_data)
{
// Do something with the data
}
private static T PtrToStruct<T>(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
{
// Invalid pointer returned
return default(T);
}
return Marshal.PtrToStructure<T>(ptr);
}
}
телефонный код (WCF службы):
using (MyClass class = new MyClass())
{
return class.GetStatus();
}
Я ушел из IDisposable код, как это было установлено в качестве одноразового использования шаблона по умолчанию, созданной визуальной студии , Как бы то ни было, каждый раз, когда я вызываю GetStatus после первого, он знает, что я уже вызывал его до того, как перезапустил приложение. Я бы хотел, чтобы он вел себя каждый раз, когда я называю это, как будто это был первый раз. Любые идеи, которые мне нужно включить в код удаления, чтобы полностью начать с нуля каждый раз, когда я создаю экземпляр моего помощника?
Если DLL не является потокобезопасной, реализация шаблона удаления не поможет многому с возможностью внутреннего коррумпированного состояния. Вам нужно убедиться, что только один поток обращается к библиотеке либо путем создания другого процесса, либо с помощью взлома с несколькими переименованными dlls. –
. Я пробовал обернуть все службы с помощью lock(), чтобы библиотека не вызывалась из нескольких потоков, однако кажется разумным к тому факту, что он уже использовался процессом раньше. –