UWP C#将UI对象返回到主线程

时间:2016-10-18 14:00:47

标签: c# multithreading uwp windows-10-universal

我正在尝试为Page类编写一个扩展方法,该方法将返回一个用户控件,该控件是根Grid的动态创建的子级。我遇到的问题是使用Content类的Page属性。

目的是返回控件以检查控件的属性,并且主要从主线程调用。

这是我正在尝试做的事情:

public static MyUserControl GetControlByTag(this Page page, int tag) {
    //throws "marshalled from a different thread" exception
    Grid rootGrid = page.Content as Grid;  

    if(rootGrid != null) {
        var controls = rootGrid.Children.OfType<MyUserControl>();

        foreach(MyUserControl control in controls)
        {
            if(control.Tag == tag) return control;
        }

    return null;
}

我已经尝试使用返回类型Task<Grid>的辅助方法来获取对象,但是我找不到同步返回异步Task的方法,我似乎无法找到同步的方法从page.Dispatcher.RunAsync()返回一个值。

这通常是XAML布局的样子:

<Page>
    <Grid>
        ...
        ...
        ...
        <MyUserControl/>
        <MyUserControl/>
        <MyUserControl/>
    <Grid/>
</Page>

1 个答案:

答案 0 :(得分:0)

我通过MSDN找到了解决方案:

public static MyUserControl GetControlByTag(this Page page, int tag) {
    MyUserControl rtn = null; 

    page.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
        Grid rootGrid = page.Content as Grid;

        if(rootGrid != null) {
            var controls = rootGrid.Children.OfType<MyUserControl>();

            foreach(MyUserControl control in controls)
            {
                if(control.Tag == tag) rtn = control;
            }
        }
    }).AsTask().Wait(); //Runs the dispatcher synchronously

    return rtn;
}

参考文章: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/e15d4852-a601-4bd6-88b4-42480fd71e70/win-rt-awaiting-the-dispatcherrunasync?forum=winappswithcsharp

编辑:但是,如果要在整个应用程序中使用它,请注意:您可能必须检查该方法是否已具有线程访问权限。我还没有找到一种优雅的方式来做到这一点,但它的基本知识看起来像这样:

public static MyUserControl GetControlByTag(this Page page, int tag) {
    Grid rootGrid = page.Content as Grid;

    if(page.Dispatcher.HasThreadAccess) {
        //Code to run
    }
    else {
        page.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
            //Code to run
        }).AsTask().Wait();
    }
}