我正在尝试使用Backgroundworker在MONO上构建应用程序。当我使用顺序方法时,我的应用程序正常工作。基本上我的应用程序在点击按钮时在绘图区域绘制一些矩形。
我试图比较顺序之间执行时间的差异,使用Backgroundworker和其他人。
我在使用后台工作程序时遇到问题,请看下面的代码,
static void DoWork (object sender, DoWorkEventArgs e)
{
Context ct = (Context)e.Argument;
house.DrawHouse rect = new house.DrawHouse ();
PointD p1, p2, p3, p4;
p1 = new PointD (55, 250);
p2 = new PointD (65, 250);
p3 = new PointD (65, 90);
p4 = new PointD (55, 90);
Gtk.Application.Invoke (delegate {
ct.MoveTo (p1);
ct.LineTo (p2);
ct.LineTo (p3);
ct.LineTo (p4);
ct.LineTo (p1);
ct.ClosePath ();
ct.Color = new Color (0, 0, 0);
ct.FillPreserve ();
ct.Color = new Color (255, 255, 255);
ct.Stroke ();
});
}
}
在上面的代码工作线程中创建了创建矩形并给GUI线程打印它。但它在 ct.MoveTo(p1);
中引发错误
希望很快听到一些人的消息。
答案 0 :(得分:1)
您确定要在GUI线程中调用该代码吗?要找到答案,您可以使用this tool。
另外,让我猜一下:你在Windows上运行它,不是吗?我得到了这样的印象,因为在MS.NET上发生的AccessViolationExceptions比在Mono上更常见(不知何故,Mono上与非托管世界的互操作性不那么严格)。
这有时会出现错误,但尚未解决。在MS.NET中,这些问题通常通过应用适当的调用约定来解决。一个例子是this,也许你错过了一些这个? (或者Cairo的绑定?一定要克隆gtk-sharp并查看被调用的DllImport;也许你可以发现一个bug并发送一个拉取请求来修复它?)
答案 1 :(得分:0)
你是对的。是的,我在Windows上运行它。对于你的第一点,工作线程将启动任务并创建矩形并给予GUI线程以在屏幕上打印它。 (Gtk.Application.Invoke(delegate {});这将切换到GUI线程)
看看下面的代码我正在做同样的事情,但不是从绘画的角度来看,但它耗费一些时间计算。耗时的计算由工作线程完成,并将结果提供给GUI线程以在UI上打印。这绝对适合我,没有任何错误。
void DoWork (object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
var watch = Stopwatch.StartNew ();
for (int i = lowerLimit; i <= upperLimit; i++) {
int j = i;
var result = SumRootN (j);
Gtk.Application.Invoke (delegate {
textview15.Buffer.Text += "root " + j.ToString () + " = " + result.ToString () + Environment.NewLine;
});
worker.ReportProgress ((int)(((double)i / (double)upperLimit) * 100));
}
var time = watch.ElapsedMilliseconds;
textview20.Buffer.Text = "Background Worker: \n execution took " + time + " MS to \n complete the execution \n SLOW & RESPONSIVE";
}
但是,如果我在绘画上做同样的事情,它会给我上面附带的错误。
如果我错了,请纠正我
感谢回复knocte,我会看看你的回复。