Sharing memory across different running applications
Introduction
Sharing memory is a powerful tool and it can now be done simply....
You have an application, will call it application "A.exe" and you would like it to pass data to your application "B.exe". How would you do this?- You could share a file, but this will be slow and if the data is used a lot? put excessive demand on your hard drive.
- You could share data across a local network link, but this just adds more overhead for your PC.
- You could share some memory, but how?
For example application "A" is a complex user interface that logs users in, reads databases and adds user form controls for controlling attached hardware. Application "B" needs to run at the same time within the same PC on another thread/CPU core. It controls hardware in real time via LAN or USB, yet needs data that would require application ‘A’s" users database results.
Sharing memory in real time is the best way. However this is not as easy as it sounds......
Background
The memory on a PC is fully managed by the operating system in this case Microsoft Windows 7. The operating system has to balance all the different running applications over several CPU cores for all of the running "threads". The applications "A" thread will have no knowledge of applications "B" thread or its memory use. So how can we set aside some memory to share some data?
In the bad old days of programming you would have typed "Reserve Memory Address XXX" and in "Basic" would have typed keywords like PEEK or POKE to place the data in. However if all your applications did this, you soon would have run out of memory, which did happen!
Until .Net Framework 4 sharing memory was hard to do. But thanks to some new functions it is really easy and your application’s doesn’t have to know anything about threads or memory as the new function takes care of the memory, thread safety all for you.
This new shared memory function is handled just like files; you open them with a name, add data to them and share them across different applications. The data can be a few bytes to Gigabytes. However I prefer to use a small "buffer file of shared memory". The task of my shared memory file is to pass variables and data from my different applications.
Another example: You could have a shared memory file called "Commands" which is only a few bytes big , sent from application A. Application B reads the commands and replies with its shared memory file called "Results" and puts them ready for application A. The combination is limitless and you can have any number of running applications.For further reading please refer to http://msdn.microsoft.com/en-us/library/dd997372.aspx
Code Description
The code Imports the System.IO.MemoryMappedFiles
namespace
which has all the classes you need for controlling memory mapped files, and waits for the buttons MakeFile
or ReadFile
mouse click events to fire.
To write some data to share in memory you do the following....
Call MakeMemoryMappedFile()
MemoryFile
"
Dim File=MemoryMappedFile.CreateOrOpen("MemoryFile",26)
Notice I have used "CreateOrOpen
" this is useful if your application
could find that another application has already opened it with the same name.
You could just use "Create
" for even more simplicity.
Now we need to make our shared memory called "MemoryFile
"
viewable to our other applications. This is done by using an object I called "writer"
and calling the method "CreatViewAccessor
". This now makes the memory file data
"Viewable
". You can set the start and size that you wish your viewing application
to see, I used 0 the Start of "bytes Array
" and the "bytes Array" length (26).
Using writer = File.CreateViewAccessor(0, bytes.Length)
With the "MemoryFile
" open and Viewable all that is left to do
is to write our byte array to the shared memory this is done with:
writer.WriteArray(Of Byte)(0, bytes, 0, bytes.Length)
To read the data in shared memory you need to do the following.....
Call ReadMemoryMappedFile()
My object "File" here is used to "Open
" an "Existing
" shared
memory file which we opened in the above method called "MemoryFile
" e.g.
Using file = MemoryMappedFile.OpenExisting("MemoryFile")
Here the Try and Catch is important to help us, as the shared memory file may not exist, so I catch the exception and simply show in a message box that it does not exist. You could add your own handler here. Note unlike standard file handling this class does not support "If.exist"
With the reader open, the class needs to know what do you want
to access and view. This is done with my object called "reader" and using"CreateViewAccessor
" method with the start and number of bytes to access.
but first I ready a buffer to hold the data bytes to be read, I’ve also called
it "bytes" , because I know how many bytes I was sending I've hard coded this the same size (26)
Then load the buffer with:
reader.ReadArray(Of Byte)(0, bytes, 0, bytes.Length)
Finally I display the bytes converted to a string in a text box. Your code could parse the bytes for commands or data for further actions or events. You should close the memory just like you would do with a file. In this example I left it open so it can be called recursively for demonstration.
The code shown here is just one form the same code is repeated in a different application I called form 2, with just the data in the write array changed to show that you can change it.
Using the Code
The demo VB.NET application is two projects in the same
VS2010 solution. It consists of one form each. It
uses the System.IO.MemoryMappedFiles
namespace in both and my example uses a
few bytes from your system memory.
Application Form1 writes a few bytes when you click the Makefile button. e.g. values 1,2,3, 4.. etc. You can read them back on the same form textbox with the ReadFile button or more importantly from the other application Form2 Readfile button.
Application Form2 Make file button puts some different data (Adds 10) to the same shared memory file so that you can see how easy it was to read the different values.
Once you play with the demo you should be able to adapt for your own applications.....
Imports System
Imports System.IO
Imports System.IO.MemoryMappedFiles
''' <summary>
''' Demo Form 1
''' </summary>
''' <remarks>
''' By David Rathbone 18/08/2011
''' Many thanks to Microsoft
''' </remarks>
Public Class Form1
''' <summary>
''' Write Memory
''' </summary>
''' <remarks></remarks>
Private Sub MakeMemoryMappedFile()
Dim File = MemoryMappedFile.CreateOrOpen("MemoryFile", 26)
Dim bytes = New Byte(25) {}
For i As Integer = 0 To bytes.Length - 1
bytes(i) = i + 1
Next
Using writer = File.CreateViewAccessor(0, bytes.Length)
writer.WriteArray(Of Byte)(0, bytes, 0, bytes.Length)
End Using
End Sub
''' <summary>
''' Read Memory
''' </summary>
''' <remarks></remarks>
Private Sub ReadMemoryMappedFile()
Try
Using file = MemoryMappedFile.OpenExisting("MemoryFile")
Using reader = file.CreateViewAccessor(0, 26)
Dim bytes = New Byte(25) {}
reader.ReadArray(Of Byte)(0, bytes, 0, bytes.Length)
TextBox1.Text = ""
For i As Integer = 0 To bytes.Length - 1
TextBox1.AppendText(CStr(bytes(i)) + " ")
Next
End Using
End Using
Catch noFile As FileNotFoundException
TextBox1.Text = "Memory-mapped file does not exist."
Catch Ex As Exception
End Try
End Sub
''' <summary>
''' Button Make File Click event
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub Btn_Make_Click(sender As System.Object, e As System.EventArgs) _
Handles Btn_Make.Click
MakeMemoryMappedFile()
End Sub
''' <summary>
''' Button Read File Click event
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub Btn_Read_Click(sender As System.Object, e As System.EventArgs) _
Handles Btn_Read.Click
ReadMemoryMappedFile()
End Sub
End Class
History
First Version 18/08/2011
Post Comment
xw29WU Looking forward to reading more. Great post.Thanks Again. Will read on...
tTgRbN Thanks for sharing, this is a fantastic blog post. Awesome.
7JSAkv wow, awesome article post. Much obliged.
Can term, you with the than discharge. could be the and can the. Details thrush the Over education, age.