编程语言
首页 > 编程语言> > c#-GTK#的同步/阻止Application.Invoke()

c#-GTK#的同步/阻止Application.Invoke()

作者:互联网

不幸的是,Application.Invoke()是异步的:

private string ThreadFunction(int i)
{
    string result = null;

    Gtk.Application.Invoke(delegate
    {
        OutputStringToUserInterface("i = " + i.ToString());
        result = GetStringFromUserInterface();
    });

    return result;
}

这意味着在此示例中,ThreadFunction()在调用Application.Invoke()之后立即进行,从而导致结果字符串可能处于未定义状态. -通常ThreadFunction()会更快,并返回旧值(即null).

这是使用ManualResetEvent使Application.Invoke()同步的解决方法:

private string ThreadFunction(int i)
{
    string result = null;

    using (var ev = new ManualResetEvent(false))
    {
        Gtk.Application.Invoke(delegate
        {
            OutputStringToUserInterface("i = " + i.ToString());
            result = GetStringFromUserInterface();

            ev.Set();
        });

        ev.WaitOne();
    }

    return result;
}

这样,ThreadFunction()一直等到Application.Invoke()返回,就像使用WinForms Control.Invoke()一样.

编辑:更好的示例代码

EDIT2:添加缺少使用

现在我的问题是:有更好的解决方案吗?

解决方法:

好吧,是的,没有理由等待委托执行以获取正确的返回值.固定:

int result = i + 1;

并且可以让OutputStringToUserInterface()异步执行,前提是您不经常调用ThreadFunction(),从而使请求泛滥到UI线程.

如果您的实际代码实际上取决于必须在UI线程上运行的函数的返回值,则不能,您无法使其更快.显然,这是您真正要避免的事情.

标签:multithreading,mono,gtk-2,c,net
来源: https://codeday.me/bug/20191210/2100608.html