Gtk.Application.Invoke不起作用

时间:2012-09-11 09:50:32

标签: c# multithreading mono monodevelop

我正在尝试使用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);

中引发错误

Following is the error

希望很快听到一些人的消息。

2 个答案:

答案 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,我会看看你的回复。