加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 当异步块并发不止一个时,抛出异常会发生什么?

发布时间:2020-12-15 22:26:28 所属栏目:百科 来源:网络整理
导读:我有一个带有TransformBlock的DataFlow,它同时运行异步磁盘Read方法.例如,从磁盘阵列读取多个文件,这些文件通过非单个读取请求队列深度提供性能优势. 直观地说,所有管道工作应该在最后一个ActionBlock完成时完成.但是,会发生以下情况: 假设Rabbit和Bear开始
我有一个带有TransformBlock的DataFlow,它同时运行异步磁盘Read方法.例如,从磁盘阵列读取多个文件,这些文件通过非单个读取请求队列深度提供性能优势.

直观地说,所有管道工作应该在最后一个ActionBlock完成时完成.但是,会发生以下情况:

假设Rabbit和Bear开始将两个文件提取到它们自己的字节缓冲区中. Rabbit抛出EatenByAWolf异常. Bear稍后完成,因为它的文件有点大.当Bear从冬季长时间休眠中醒来时,EatenByAWolf异常似乎已经传播到最后一个ActionBlock的Completion等待站点.好吧,问题是我在这里清理Rabbit和Bear的字节缓冲区,导致Bear阻塞NullRefToBuffer异常.

推荐的方法是什么?我是否还应该在清除缓冲区之前等待Reader块(包含所有动物)完成,还是可以更优雅地处理?

Task.WaitAll(new[] { readerBlock.Completion,lastActionBlock.Completion });

lastActionBlock.Completion.Wait();

解决方法

我在错误的抽象级别管理字节缓冲区.

对我来说,解决方案是在创建执行多个异步读取的TransformBlock时使用有状态读取器对象.添加ConcurrentBag<>缓冲区到MyFileReaderWithCachingByteBuffers读取器对象确保缓冲区不会被清除,直到闭包捕获的读取器对象超出范围.只有当所有读取操作都完成时才会发生

var fileReader = new MyFileReaderWithCachingByteBuffers(biggestFileSize);
var readerBlock = new TransformBlock<string,MyObject>(
           animal => fileReader.ReadAsync(animal),new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = customDOP });

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读