Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-Process Locking in C#

I've written an API that will be used on the same box in (1) a windows service, (2) a web application, and (3) a windows forms application. They all need to share a very small set of common data (a few ints, a date, and a string that I could put as properties of a single class).

What sort of locking mechanism can I use cross-process so that the three processes can share the resources safely and not run into conflicts?

No databases please, looking for a solution that doesn't require additional dependencies. Preferably the solution would use shared memory, or the file system in some way.

like image 260
Langdon Avatar asked Sep 03 '10 19:09

Langdon


5 Answers

For cross-process locking in C#/.Net, you can use a named system Mutex.

like image 61
quentin-starin Avatar answered Nov 03 '22 15:11

quentin-starin


Use an EventWaitHandle object to construct a named event that each process can lock or block on. Works in .NET 2.0 and later.

like image 41
dthorpe Avatar answered Nov 03 '22 13:11

dthorpe


You can use MSMQ to provide shared queues between your applications, with one of the applications acting as the master; the Windows service would be the best choice if it's always running.

I use System.Data.Sqlite for communicating between Windows services and applications. Even though you said no databases, you might find this a worthy compromise. It's an embedded database with no admin burden. You "ship" it by including a single DLL in your applications, and it saves your data in a single file.

Think of it as a persistent file that you access using SQL statements via ADO.Net; it even sports a LINQ interface. You get locking through standard transactions (with rollback) and it also offers encryption. You can modify and view its contents using the Visual Studio Service Explorer. It works on .Net 3.5 and .Net 4. And it's open-source with no restrictions. You can add columns and tables without breaking existing functionality. Since deployment is as simple as adding a DLL to your solution, it's much easier to deploy and support. And since the connection string points to a file, it makes it easy to hit it from remote machines. Perhaps not as elegant as shared queues or mutexes, but its greatly simplified things for me.

like image 3
Ed Power Avatar answered Nov 03 '22 13:11

Ed Power


If all your application would reside on one machine, than you could use interprocess synchronization primitives like named mutexes and shared memory.

But I think much better approach would be to use something like WCF services (that could reside in windows service) and to expose all necessary information through specified contract. In this case all this application could reside on different machines, but anyway this solution more clean and robust.

like image 1
Sergey Teplyakov Avatar answered Nov 03 '22 13:11

Sergey Teplyakov


Based on your question, it sounds like what you need it cross process communication. So one of the processes hosts the shared data and the other processes need to access that data.

If the above is correct, you could use simple in process locking like a Monitor to protect the shared data and expose a WCF endpoint to provide access to the data from another process. Using a Named Pipe transport for the WCf communication, will be very efficient for communication between processes on the same box.

There would be no need for cross process locking, unless you used a shared resource like a memory mapped file to share the data, but to be honest this would be cumbersome and require you to handle many things manually that WCF would take care of with the benefit that you could eventually scale of the single box to multiple boxes if you ever needed to.

like image 1
Chris Taylor Avatar answered Nov 03 '22 14:11

Chris Taylor