views:

688

answers:

2

Hi, I'm having some problems with concurrency when using DLLImport, I have a Dll that provides some report I need to send over the web, so I have this:

[DllImport("Rep.dll", EntryPoint = "PrintRep", CallingConvention = CallingConvention.StdCall, 
CharSet = CharSet.Ansi)]
private static extern string PrintRep(several params...);

And over the Dll side there's lots of variables and instances that then returns a path with the report.

The code I have now has a lock around the call of PrintRep, which works, but obviously makes pending requests wait, is there a way for this to work without a lock? Because if I take out the lock I get several "Attempt to write on protected memory" errors and the Dll eventually hangs.

A: 

If all web requests are waiting based on this call, you should consider calling this on a separate thread, keeping the lock, and making only the PrintRep call requestor waiting for the call to return to wait.

If only people waiting for the PrintRep call to complete are the ones waiting, there isn't much you can do, outside of implementing some kind of server-side work queue, and getting users to return to check the queue somehow, perhaps by a timed AJAX callback.

Whatever you do, avoid calling this on any ThreadPool thread. ASP.Net uses those to handle page requests.

codekaizen
+1  A: 

Is the report DLL thread safe? I'm going to guess no, since you said that if you remove the lock then you get errors. So, you have two choices, make the DLL threadsafe (requires source and changes to old dll), or serialize the requests to the DLL, which you've done. Those are your only two choices. However, do you need to make your users wait for the report right then? Can you, perhaps, maintain a list of users waiting for the report, and the parameters needed for the call, and then return the webpage to the user letting them know you'll email them the report. Then you can process the reports in a serial manner while not causing your users to wait for the result.

WaldenL