如果我们从不同的进程运行它,那么async和等待代码的行为会有所不同

时间:2017-08-14 16:34:14

标签: c# asynchronous async-await console-application filesystemwatcher

请耐心等待这个长期的问题。

方案: 我在根目录上有一个FileSystemWatcher,它正在控制目录中的控制文件上查看LastWrite更改。看起来像这样: -

  

root-directory FileSystemWatcher实例正在关注此根目录)

     

|

     

| ----- control-directory_0 \ control-file

                      \ data-file
     

| ----- control-directory_1 \ control-file

                      \ data-file
     

| ----- control-directory_2 \ control-file

                      \ data-file
     

| ----- control-directory_3 \ control-file

                      \ data-file
     

.........更类似的结构(但只有一个根目录

抱歉我的创意绘图。

我遇到的问题是, root-directory (大约200-500)内可以有很多控制目录,还有 control-directory& #39; s 控制文件,其中有一个数据文件(在每个文件中),其中正在进行连续写入。

我正在关注NotifyFilter.LastWriteFilter = control-fileInternalBufferSize设置为4KB(请不要求增加此内容,我不允许修改它,并且由于要求而导致事件为8KB(默认值为1),我无法使用{ {1}}用于每个控制文件,因为它会占用大量宝贵的非分页内存。)

我的FileSystemWatcher看起来像这样

EventHandler

目前,我正在处理300个控制文件。由于数据文件上发生了大量写操作,而且很多请求都发送到控制文件,我的缓冲区会经常溢出。

然后我想到了一个主意。 ( private void OnChange(Object sender, FileSystemEventArgs eventArgs) { //result = CPU bound work here //evaluating result } async与[{1}}战斗坦克的救援)

await

它工作正常,我能够处理大量请求(甚至测试了1000个事件,只有4KB缓冲区)。

现在是有趣的部分。我是如何测试的?

涉及两个实体,一个是写入控件数据文件,另一个是处理由写入控件生成的事件 - 文件的。所以我上去创建了一个控制台应用程序,它完成了这两件事。

Task

接下来,我测试了两个控制台应用程序: -

首先,负责并行地将数据写入各种控制文件 - ( Writer_App )。

其次,负责处理事件 - ( Event_Handling_App )。

注意:核心中没有代码更改,但现在我不是在同一个控制台应用程序中编写和处理事件,而是从一个处理并处理其他表单。

所以我将两个实体与我的旧控制台app分开(将模拟开始到实际环境)。现在我通过先运行 Event_Handling_App 开始测试,然后通过运行 Writer_App 写入控制文件,现在事情变得奇怪了我的应用程序对于相同数量的控制文件,如果我没有 async private void OnChange(Object sender, FileSystemEventArgs eventArgs) { var result = await Task.Run(() => Work.CPUboundWork()); //evaluating result } static void Main(string[] args) { int controlFileCount = Convert.ToInt32(args[0]); string basePath = args[1]; //CreateFolderStructure(basePath, controlFileCount); for first run. FileSystemWatcher baseDirectoryWatcher = new FileSystemWatcher(); SetupFileSystemWatcher(baseDirectoryWatcher, basePath); WriteToControlFilesParallely(basePath, controlFileCount); Console.Read(); } public void SetupFileSystemWatcher(FileSystemWatcher baseDirectoryWatcher, string path) { //setting properties of the watcher. baseDirectoryWatcher.NotifyFilter = NotifyFilter.LastWrite; baseDirectoryWatcher.Filter = "control-file"; baseDirectoryWatcher.InternalBufferSize = 4096; baseDirectoryWatcher.Path = path; baseDirectoryWatcher.IncludeSubdirectories = true; baseDirectoryWatcher.EnableRaisingEvents = true; } public void WriteToControlFilesParallely(string basePath, int controlFileCount) { Parallel.For(0, controlFileCount, (i) => { string filePath = Helper.GetFilePath(basePath, i); Helper.WriteData(filePath, "data"); }); } ,则会面临相同数量的写入InternalBufferOverflow异常我的第一次实施。

我再次测试了一个控制台应用程序(它有两个职责)并且它运行正常。

  

那么,为什么两个控制台应用程序会使asyncawait(以及async)的魔力在一个控制台应用程序运行良好时消失?

     

它与Inter Process Communication有关吗?

     

我想知道它是否可以在生产中使用,因为我将在Web应用程序中使用处理程序代码,而其他一些进程可以通过网络编写这些文件。

1 个答案:

答案 0 :(得分:1)

最后,我能够弄清楚这一点,当我使用单一控制台应用程序时,我正在运行其exe(通过cmd),但当我尝试使用两个控制台应用程序时,我在visual studio中运行应用程序(在发布模式下) )所以由于这个(加载了视觉工作室)我得到了例外,我责备asyncawait

因此,如果您正在处理紧张的代码,请始终从exe运行您的应用程序。