Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# ArgumentOutOfRangeException在访问集合时,即使索引未超出范围,也会发生异常?_C#_Multithreading_Collections - Fatal编程技术网

C# ArgumentOutOfRangeException在访问集合时,即使索引未超出范围,也会发生异常?

C# ArgumentOutOfRangeException在访问集合时,即使索引未超出范围,也会发生异常?,c#,multithreading,collections,C#,Multithreading,Collections,我有一个应用程序,它在一个线程中通过一系列图像过滤器处理图像,并在另一个线程的UI中显示图像。简化图像过滤器类如下所示: //此类表示GPU上的筛选器操作。 //筛选器处理线程重复调用Process()。 类ShaderFilterBase:IFilter { //此变量保存图像操作的结果。 私有图像信息结果图像信息; //指示调用Render()是否已更新图像 bool hasChanged=true; 公共i收集结果 { 得到 { ICollection results=新集合(); 添加(

我有一个应用程序,它在一个线程中通过一系列图像过滤器处理图像,并在另一个线程的UI中显示图像。简化图像过滤器类如下所示:

//此类表示GPU上的筛选器操作。
//筛选器处理线程重复调用Process()。
类ShaderFilterBase:IFilter
{
//此变量保存图像操作的结果。
私有图像信息结果图像信息;
//指示调用Render()是否已更新图像
bool hasChanged=true;
公共i收集结果
{
得到
{
ICollection results=新集合();
添加(GetEffectResult());
返回结果;
}
}
公共ICollection进程(ICollection图像)
{
//我们只有在只有一个图像的情况下才处理图像。
//如果GPU必须处理多个图像,则此方法
//应在派生类中重写。
如果(images.Count==1)
{
ImageInfo firstImage=images.First();
//如果提供的图像已经是GPU上的着色器资源,
//我们不需要再次将纹理上传到GPU。我们只需要
//将所提供图像的输出纹理设置为输入纹理
//当前图像的。
if(firstImage.IsShaderResource)
SetResource(firstImage.ShaderResourceView);
其他的
上传输入文本(firstImage);
Render();
firstImage.ShaderResourceView=输出ShaderResourceView;
}
返回图像;
}
公共虚拟void Render()
{
监视。输入(此);
//在GPU上执行纹理操作
hasChanged=true;
监控。退出(本);
}
公共图像信息GetEffectResult()
{
监视。输入(此);
如果(已更改)
{
//从GPU下载图像并将其存储在resultImageInfo中
hasChanged=false;
}
监控。退出(本);
返回resultImageInfo;
}
}
此外,我有各种派生类,它们因要在GPU上执行的HLSL着色器程序而异。图像处理线程迭代这些过滤器实例的集合。GetEffectResult()仅在图像需要从视频内存下载到系统内存时调用。我使用Monitor.Enter(this),因为每个过滤器实例保证在过滤器链中只存在一次

为了设置和配置过滤器,我有一个UI,它显示过滤器链中每个过滤器的输出。过滤器实例由过滤器模型封装,这些模型由WPF UI使用

内部抽象类FilterModelBase:DependencyObject
{
私有可写位图预览;
私有静态只读DependencyPropertyKey PreviewPropertyKey=DependencyProperty.RegisterReadOnly(“预览”,
typeof(ImageSource)、typeof(FilterModelBase)、newpropertyMetadata();
//WPF窗口包含绑定到此属性的图像控件。
公共静态只读DependencyProperty PreviewProperty=PreviewPropertyKey.DependencyProperty;
公共图像源预览
{
获取{return(ImageSource)GetValue(PreviewProperty);}
私有集{SetValue(PreviewPropertyKey,value);}
}
//底层过滤器。
公共IFilter过滤器
{
获取{返回this.filter;}
}
受保护的筛选器模型库(IEventAggregator事件聚合器、IFilter筛选器)
{
Check.NotNull(filter,“filter”);
this.EventAggregator=EventAggregator;
this.filter=过滤器;
}
//更新过滤器输出预览。
公共虚拟无效刷新(调度程序)
{
如果(!dispatcher.CheckAccess())
调用(新操作(()=>Refresh(dispatcher));
其他的
{
ImageInfo filterImage=null;
Monitor.Enter(此.filter);
if(this.filter!=null&&this.filter.LastResults.Count>0)
filterImage=this.filter.LastResults.ElementAtOrDefault(0);
if(filterImage!=null)
{
this.preview.WritePixels(新的Int32Rect(0,0,filterImage.Width,filterImage.Height),
filterImage.ImageBytes,filterImage.Width*filterImage.Channels,0);
}
Monitor.Exit(这个.filter);
}
}
UI线程通过计时器重复调用每个过滤器模型实例的Refresh()方法

每隔一段时间,我会在下面的行中得到ArgumentOutOfRangeException:

filterImage = this.filter.LastResults.ElementAtOrDefault(0);

但是,当我检查LastResults属性时,它包含一个元素,就像它应该包含的一样。即使调试器说集合实际上只包含一个项,并且我总是访问集合中的第一个项,但怎么可能引发ArgumentOutOfRangeException呢e debuggerafter引发了异常after。可能是在visual studio停止调试器的所有操作时,另一个线程插入了元素


HTH

这是一个挑衅性的标题,尽管我倾向于相信异常是正确的,而不仅仅是开玩笑。应用程序是多线程的吗?时不时==线程竞赛。@Micheal:你试过这个了吗。filter.LastResults[0]如果您已经尝试过,那么在异常发生后重新尝试在快速午餐窗口重新执行命令,这样您就可以确保在HTH所说的异常抛出之后,调试器不重新评估该属性。使用监视器而不尝试。最后是有风险的。请考虑使用锁语句。同时,避免锁定<代码。>此