4

I want something like a static class variable, except when different applications load my assembly I want them all to be sharing the same variable.

I know I could write to disk or to a database, but this is for a process that's used with sql queries and that would probably slow it down too much (actually I am going to test these options out but I'm asking this question in the meantime b/c I don't think it's going to be an acceptable solution).

I would prefer to use the solution that incurrs the least overhead in deployment, and I don't mind if the solution isn't easy to create so long as it's easy to use when I'm done.

I'm aware that there are some persistent memory frameworks out there. I haven't checked any of them out yet and maybe one of them would be perfect so feel free to recommend one. I am also perfectly content to write something myself, particularly if it makes deployment easier for me to do so.

Thanks in advance for any and all suggestions!

Edit: Looks like I was overlooking a really easy solution. My problem involved SQL only providing 8000 bytes of space to serialize data between calls to a SQL aggregate function I wrote. I read an article on how to compress your data and get the most out of that 8000 bytes, and assumed there was nothing more I could do. As it turns out, I can set the MaxBytes = -1 instead of a range between 0 to 8000 to get up to 2gb of space. I believe that this was something new they added in the 3.5 framework because there are various articles out there talking about this 8000 byte limitation.

Thank you all for you answers though as this is a problem I've wanted to solve for other reasons in the past and now I know what to do if I need a really easy and fast way to communicate between apps.

Brandon Moore
  • 8,590
  • 15
  • 65
  • 120

3 Answers3

5

You can't store this as in-memory data and have it shared between processes, since each process has it's own isolated memory address space.

One option, however, would be to use the .NET Memory-mapped file support to "store" the shared data. This would allow you to write a file that contained the information in a place that every process could access.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Wow this is really cool. This would work great for concurrently running instances, but in my case they aren't running at the same time though. Sounds like the memory would be lost (or persisted to disk, which defeats the purpose) in between instances though, right? – Brandon Moore Nov 10 '11 at 01:49
  • 1
    @BrandonMoore If you want shared data between two instances that aren't running at teh same time, you pretty much need to persist it... What are you trying to accomplish? – Reed Copsey Nov 10 '11 at 01:53
  • A sql aggregate mode function. I.e. "Select description, dbo.mode(price) from products group by style". Sorry didn't say that earlier, but I wanted to get back the sort of answers I've gotten back so far first before hearing the alternative solutions people would otherwise be suggesting. Problem is that the interface SQL provides for implementing an aggregate function uses a serializer that only allows for 8000 bytes. – Brandon Moore Nov 10 '11 at 02:02
2

Each process has its own address space. You cannot simply share a variable like you intend

You can use shared memory though.

If you are on .NET 4, you can simply use Memory-Mapped Files

Community
  • 1
  • 1
parapura rajkumar
  • 24,045
  • 1
  • 55
  • 85
  • I'm guessing that with either of these options, I'm going to need some sort of background app to hold a reference to the memory I'm using or it will be released between instances... – Brandon Moore Nov 10 '11 at 01:53
  • if you really need to cache some serious amount of data between processes look into products that are designed like memcached ( http://en.wikipedia.org/wiki/Memcached ). – Alexei Levenkov Nov 10 '11 at 02:09
  • You don't need a background app. You can use **MemoryMappedFile.CreateOrOpen** – parapura rajkumar Nov 10 '11 at 02:13
  • parapura: The documentation for the Memory Mapped classes states that when your objects go away so does your memory (if you have the option set then it will be persisted to an actual file, but that defeats the purpose. – Brandon Moore Nov 12 '11 at 01:52
1

If you want some sort of machine-wide count or locking you can look into use of named synchronization objects like semaphore - http://msdn.microsoft.com/en-us/library/z6zx288a.aspx or mutexes http://msdn.microsoft.com/en-us/library/hw29w7t1.aspx. When name is specified such objects are machine-wide instead of process-wide.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Part of my problem is size. An interface I'm using actually provides for the use of a binary serializer to persist data between instances, but the problem is it allows for a max of 8000 bytes and that's too small. Would that be an issue here? – Brandon Moore Nov 10 '11 at 01:57
  • Clearly you need something else - synchronization objects can't hold anything beyond single count. – Alexei Levenkov Nov 10 '11 at 02:06
  • I was thinking that would probably be the case. Interesting thought though for sure. – Brandon Moore Nov 12 '11 at 01:49