The challenge I'm facing is that I'm writing a WCF service which is by it's nature, multithreaded to work with a C library which I know is not threadsafe and I have no option to influence the library I'm calling. The library I'm calling has an initialisation method to configure the hardware and set a callback handler.
If I execute this process in a console app, it runs absolutely fine as it's on a single thread.
To overcome the challenges I've created a helper class which implements IDisposable to setup the hardware, make the calls and hopefully rip itself down once it's finished.
Sample helper class:
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);
}
}
Calling code (WCF service):
using (MyClass class = new MyClass())
{
return class.GetStatus();
}
I've left out the IDisposable code as it's been set as the default disposable pattern created by visual studio. As it stands, each time I call GetStatus after the first it knows I've already called it before until I restart the application. I'd like it to behave each time I call it as though it was the first time. Any ideas what I need to include in the disposal code to completely start from scratch each time I create an instance of my helper?