C# 死锁问题
您好,下面的代码有死锁问题。调用函数getMap()时会发生这种情况。但我真的看不出是什么原因造成的C# 死锁问题,c#,com-interop,deadlock,C#,Com Interop,Deadlock,您好,下面的代码有死锁问题。调用函数getMap()时会发生这种情况。但我真的看不出是什么原因造成的 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.Threading; using AForge; using AForge.Imaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using AForge;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Imaging.Textures;
using AForge.Math.Geometry;
namespace CDIO.Library
{
public class Polygon
{
List<IntPoint> hull;
public Polygon(List<IntPoint> hull)
{
this.hull = hull;
}
public bool inPoly(int x, int y)
{
int i, j = hull.Count - 1;
bool oddNodes = false;
for (i = 0; i < hull.Count; i++)
{
if (hull[i].Y < y && hull[j].Y >= y
|| hull[j].Y < y && hull[i].Y >= y)
{
try
{
if (hull[i].X + (y - hull[i].X) / (hull[j].X - hull[i].X) * (hull[j].X - hull[i].X) < x)
{
oddNodes = !oddNodes;
}
}
catch (DivideByZeroException e)
{
if (0 < x)
{
oddNodes = !oddNodes;
}
}
}
j = i;
}
return oddNodes;
}
public Rectangle getRectangle()
{
int x = -1, y = -1, width = -1, height = -1;
foreach (IntPoint item in hull)
{
if (item.X < x || x == -1)
x = item.X;
if (item.Y < y || y == -1)
y = item.Y;
if (item.X > width || width == -1)
width = item.X;
if (item.Y > height || height == -1)
height = item.Y;
}
return new Rectangle(x, y, width-x, height-y);
}
public Point[] getMap()
{
List<Point> points = new List<Point>();
lock (hull)
{
Rectangle rect = getRectangle();
for (int x = rect.X; x <= rect.X + rect.Width; x++)
{
for (int y = rect.Y; y <= rect.Y + rect.Height; y++)
{
if (inPoly(x, y))
points.Add(new Point(x, y));
}
}
}
return points.ToArray();
}
public float calculateArea()
{
List<IntPoint> list = new List<IntPoint>();
list.AddRange(hull);
list.Add(hull[0]);
float area = 0.0f;
for (int i = 0; i < hull.Count; i++)
{
area += list[i].X * list[i + 1].Y - list[i].Y * list[i + 1].X;
}
area = area / 2;
if (area < 0)
area = area * -1;
return area;
}
}
}
错误消息
CLR无法转换
从COM上下文0x1bb7b6b0到COM
上下文0x1bb7b900持续60秒。这个
拥有目标的线程
上下文/公寓是最有可能的
进行非泵送等待或
处理一个非常长的运行时间
无泵送窗操作
信息。这种情况普遍存在
对绩效产生负面影响,并可能
甚至导致应用程序变得
无响应或内存使用
随着时间的推移不断积累。到
避免这个问题,所有的单
螺纹单元(STA)螺纹
应该使用泵送等待原语
(如CoWaitForMultipleHandles)和
在长时间内定期发送消息
运行操作
在getMap()中锁定实例“hull”,然后调用getRectangle();您正试图通过“外壳”枚举 在getMap()中锁定实例“hull”,然后调用getRectangle();您正试图通过“外壳”枚举 在本msdn中,他们解释了为什么最好只在lock语句中定义一个变量。显然,它避免了许多此类问题。在本msdn中,他们解释了为什么最好只在lock语句中定义一个变量。显然,它避免了许多此类问题。这是一个托管调试助手警告,与在线程上使用COM服务器有关。COM的一个特性是,它自动处理不支持多线程的组件的线程。它会自动将方法调用从后台线程封送到UI线程,这样组件就不会以线程不安全的方式使用。这是完全自动的,您不需要自己编写任何代码来实现这一点 要使其正常工作,UI线程必须处于空闲状态,以便可以执行方法调用。警告告诉您UI线程有一分钟没有空闲,它会阻止调用完成。最可能的原因是UI线程正在阻塞,等待线程完成。这种情况永远不会发生,它已经陷入僵局。或者,它可能只是在那一分钟忙于运行代码,从来没有抽出时间来完成它的正常任务,不断循环消息。不泵送消息循环会阻止封送调用完成并触发警告 这应该是显而易见的,你的应用程序的主窗口应该被冻结,并在标题栏中显示“未响应”消息。当您使用Debug+breakall、Debug+Windows+Threads并切换到UI线程,然后查看调用堆栈时,您应该会看到UI线程死锁的位置。通过不让UI线程等待线程或避免在工作线程上使用COM组件来修复它。如果它完全不合适(不应该),那么您可以关闭带有调试+异常的警告
这是对警告的技术解释。令人厌烦的是,VisualStudio2005的RTM版本中有一个bug。调试器出了问题,在单步执行或检查变量时,它倾向于使MDA跳闸。这在Service Pack 1中得到了修复,如果您尚未完成此操作,请确保下载并安装它。这是一个托管调试助手警告,与在线程上使用COM服务器有关。COM的一个特性是,它自动处理不支持多线程的组件的线程。它会自动将方法调用从后台线程封送到UI线程,这样组件就不会以线程不安全的方式使用。这是完全自动的,您不需要自己编写任何代码来实现这一点 要使其正常工作,UI线程必须处于空闲状态,以便可以执行方法调用。警告告诉您UI线程有一分钟没有空闲,它会阻止调用完成。最可能的原因是UI线程正在阻塞,等待线程完成。这种情况永远不会发生,它已经陷入僵局。或者,它可能只是在那一分钟忙于运行代码,从来没有抽出时间来完成它的正常任务,不断循环消息。不泵送消息循环会阻止封送调用完成并触发警告 这应该是显而易见的,你的应用程序的主窗口应该被冻结,并在标题栏中显示“未响应”消息。当您使用Debug+breakall、Debug+Windows+Threads并切换到UI线程,然后查看调用堆栈时,您应该会看到UI线程死锁的位置。通过不让UI线程等待线程或避免在工作线程上使用COM组件来修复它。如果它完全不合适(不应该),那么您可以关闭带有调试+异常的警告
这是对警告的技术解释。令人厌烦的是,VisualStudio2005的RTM版本中有一个bug。调试器出了问题,在单步执行或检查变量时,它倾向于使MDA跳闸。这在Service Pack 1中得到了修复,如果您还没有这样做,请务必下载并安装它。但是getRectangle()正在同一线程上被调用,因此锁不会阻止简单列表的枚举,是吗?在同一线程中迭代锁定的列表没有任何问题。但是getRectangle()是在同一线程上调用的,因此锁不会阻止简单列表的枚举,对吗?在同一线程中迭代锁定列表没有任何问题。您引用System.Threading,但我看不到使用该命名空间的任何内容。你在别的地方纺线吗?如果是这样,他们对多边形调用了什么方法?这实际上(不知何故)是一个数据库死锁吗?你能用pos吗
if (inPoly(x, y))
points.Add(new Point(x, y));