Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有单个写入程序的MemoryMappedFile是否需要同步_C#_Web Services_Synchronization_Memory Mapped Files - Fatal编程技术网

C# 具有单个写入程序的MemoryMappedFile是否需要同步

C# 具有单个写入程序的MemoryMappedFile是否需要同步,c#,web-services,synchronization,memory-mapped-files,C#,Web Services,Synchronization,Memory Mapped Files,我有一个处理Excel文件(以前上传到服务器)的web服务,它涉及大量数据库更新,需要花费相当长的时间。我想提供另一个web服务,可以调用它来检查这个过程的进度。它将进程的ID(可能是GUID)作为输入,并返回一个int(0-100)来指示进度 我的想法是,长期运行的服务可以创建一个只包含内存的MemoryMappedFile(MMF)-只需要sizeof(int)字节,它会每隔一段时间报告它的进度。然后,“progress”服务可以打开MMF,读取int,并向调用者报告 我有两个问题。首先,我

我有一个处理Excel文件(以前上传到服务器)的web服务,它涉及大量数据库更新,需要花费相当长的时间。我想提供另一个web服务,可以调用它来检查这个过程的进度。它将进程的ID(可能是GUID)作为输入,并返回一个
int
(0-100)来指示进度

我的想法是,长期运行的服务可以创建一个只包含内存的
MemoryMappedFile
(MMF)-只需要
sizeof(int)
字节,它会每隔一段时间报告它的进度。然后,“progress”服务可以打开MMF,读取
int
,并向调用者报告


我有两个问题。首先,我对MMF没有太多经验,所以这里是否存在一些我可能不知道的陷阱?其次,更重要的是,考虑到只有一个编写器,在这种情况下是否需要同步?搜索一段时间后,我无法发现
MemoryMappedViewAccessor.Write
是否是
int
s的原子。

我起初不确定,因为我以前没有在IPC中使用MMFs,但我现在使用它进行了测试

简单的回答是不,同步是不必要的(如果您仔细考虑的话,这是有意义的)。您有以下两个示例-编写器进程和读取器进程,作为控制台应用程序

唯一的问题是,您希望在每次读/写之后将写/读流中的光标位置重置为0,或者为前32位创建视图映射。不确定第二个是否有效(很可能不起作用,您仍然需要重置文件指针)

编写器进程:

    static void Main(string[] args)
    {
        using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 10000))
        {
            int i = 0;
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    while (i++ < 10000)
                    {
                        writer.Write(i);
                        Thread.Sleep(50);
                        writer.Seek(0, SeekOrigin.Begin);
                    }
                }
            }

            Console.WriteLine("Done");
            Console.ReadLine();
        }
    }
我故意让读者在阅读之间的等待时间少于作者在写作之间的等待时间,以确保没有巧合

输出如预期,但未等待完成:

Process A says: 85
Process A says: 85
Process A says: 85
Process A says: 86
Process A says: 86
Process A says: 87
Process A says: 87
Process A says: 87
Process A says: 88
Process A says: 88
Process A says: 89
Process A says: 89
Process A says: 89
Process A says: 90
Process A says: 90
Process A says: 91
Process A says: 91
Process A says: 91
Process A says: 92
Process A says: 92
Process A says: 93
Process A says: 93
Process A says: 93
Process A says: 94

尽管如此,我还是不推荐MMF。根据您的描述,您可以在报告进度的服务中静态地(可能在并发集合中)存储进度而不发出任何问题。您可以通过仅公开另一个端点或方法来解决此问题,第二个服务可以调用该端点或方法来更新特定客户端/文件的进度。当它完成时,它只是告诉它从内存中删除它

考虑不使用共享内存。相反,向处理应用程序发送请求,并将进度作为响应接收。使用诸如HTTP之类的高级协议。http服务器和客户端都是内置在.NET中的易于使用的类。@usr:我不确定我是否理解你的建议。这两个web服务将由同一个客户端调用(使用jQuery)。它的工作原理如下:1)调用服务A开始处理文件并等待响应,2)立即开始轮询服务B的进度(网页上的进度条将被更新)。一旦对服务A的调用返回(即处理完成),它就会停止轮询服务B。这些是什么类型的web服务?WebAPI,基于WCF?@marceln:我不确定这有什么关系,但我使用的是ServiceStack。因为我想建议
SignalR
向客户报告进度。我还建议长时间运行的进程将进度存储在数据库中,而不是文件中,基于signar的进程将从中读取/检查进度,然后将其发送到相应的客户端。
Process A says: 85
Process A says: 85
Process A says: 85
Process A says: 86
Process A says: 86
Process A says: 87
Process A says: 87
Process A says: 87
Process A says: 88
Process A says: 88
Process A says: 89
Process A says: 89
Process A says: 89
Process A says: 90
Process A says: 90
Process A says: 91
Process A says: 91
Process A says: 91
Process A says: 92
Process A says: 92
Process A says: 93
Process A says: 93
Process A says: 93
Process A says: 94