2011-10-11 9 views
7

¿Hay alguna forma de utilizar los métodos Interlocked.CompareExchange(); y Interlocked.Increment(); con los valores almacenados en un archivo mapeado en memoria?Cómo usar operaciones entrelazadas contra archivos mapeados en memoria en .Net

Me gustaría implementar un servicio de subprocesos múltiples que almacenará sus datos en un archivo mapeado en memoria, pero dado que es multiproceso, debo evitar las escrituras en conflicto, por lo tanto me pregunto sobre las operaciones Interbloqueadas en lugar de utilizar bloqueos explícitos.

Sé que es posible con código nativo, pero ¿se puede hacer en código administrado en .NET 4.0?

+0

También buscando esto. ¿Encontraste alguna solución? – TravisWhidden

+0

Publicó una respuesta a continuación. ¡¡¡Por favor acepta!!! :) Gracias. – TravisWhidden

Respuesta

6

OK, esta es la forma de hacerlo! ¡Tuvimos que resolver esto, y pensé que podríamos devolver algo a stackoverflow!

class Program 
{ 

    internal static class Win32Stuff 
    { 
     [DllImport("kernel32.dll", SetLastError = true)] 
     unsafe public static extern int InterlockedIncrement(int* lpAddend); 
    } 

    private static MemoryMappedFile _mmf; 
    private static MemoryMappedViewStream _mmvs; 

    unsafe static void Main(string[] args) 
    { 
     const int INT_OFFSET = 8; 

     _mmf = MemoryMappedFile.CreateOrOpen("SomeName", 1024); 

     // start at offset 8 (just for example) 
     _mmvs = _mmf.CreateViewStream(INT_OFFSET, 4); 

     // Gets the pointer to the MMF - we dont have to worry about it moving because its in shared memory 
     var ptr = _mmvs.SafeMemoryMappedViewHandle.DangerousGetHandle(); 

     // Its important to add the increment, because even though the view says it starts at an offset of 8, we found its actually the entire memory mapped file 
     var result = Win32Stuff.InterlockedIncrement((int*)(ptr + INT_OFFSET)); 
    } 
} 

¡Esto funciona, y funciona en múltiples procesos! ¡Disfruta siempre de un buen desafío!

+0

¿Sabes cuál es la solución adecuada para x64? Dado que las funciones con enclavamiento interno no se exportan de la versión de 64 bits de kernel32.dll – Jan

+0

No encontré una solución para x64, pero sí nos topamos con eso unos meses atrás al apuntar a AnyCPU con sistema operativo de 64 bits. ¡Cualquier idea es bienvenida! – TravisWhidden

+0

¿Por qué no usaste .Net Interlocked.Increment? –

Cuestiones relacionadas