C# Gtk.Application.Invoke不工作

C# Gtk.Application.Invoke不工作,c#,multithreading,mono,monodevelop,C#,Multithreading,Mono,Monodevelop,我正在尝试使用Backgroundworker在MONO上构建一个应用程序。当我使用顺序方法时,我的应用程序运行良好。基本上,我的应用程序在单击按钮的绘图区域上绘制一些矩形 我试图比较顺序、使用Backgroundworker和其他方法在执行时间上的差异 我在使用后台工作程序时遇到问题,请看下面的代码 static void DoWork (object sender, DoWorkEventArgs e) { Context ct = (Context)e.Ar

我正在尝试使用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)中抛出了一个错误


希望不久能收到您的来信。

您确定要在GUI线程中调用该代码吗?要找到答案,你可以使用

还有,让我猜猜:你是在Windows上运行的,不是吗?我之所以有这样的印象,是因为AccessViolationException在MS.NET上比在Mono上发生得更频繁(不知何故,与非托管世界的互操作性在Mono上没有那么严格)


这有时会在bug中出现,但尚未修复。在MS.NET中,这些问题通常通过应用适当的调用约定来解决。举个例子,也许你遗漏了一些?(或者Cairo的绑定?一定要克隆并查看正在调用的DllImport;也许您可以在那里发现一个bug并发送一个请求来修复它?

您是正确的。是的,我正在windows上运行这个。对于您的第一点,worker线程将启动任务并创建矩形,并将其交给GUI线程在屏幕上打印(Gtk.Application.Invoke(委托{});这将切换到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"; 
}
void DoWork(对象发送方,DoWorkEventArgs e)
{
BackgroundWorker worker=发件人作为BackgroundWorker;
var watch=Stopwatch.StartNew();
for(int i=下限;i