简体   繁体   English

如何从 UI 线程调用方法?

[英]How do you call a method from a UI thread?

I am trying to access the Microsoft Store from a multi-threaded program.我正在尝试从多线程程序访问 Microsoft Store。 The program itself work well - no problems there, but the method该程序本身运行良好 - 没有问题,但方法

Windows.Foundation.IAsyncOperation<StorePurchaseResult> purchase = product.RequestPurchaseAsync();

throws the exception:抛出异常:

"Invalid window handle.\r\n\r\nThis function must be called from a UI thread" “window 句柄无效。\r\n\r\n必须从 UI 线程调用此 function”

My code is as follows...我的代码如下...

        private void testButton_Click(object sender, EventArgs e)
        {
            //Dispatcher dispUI = Dispatcher.CurrentDispatcher;
            //dispUI.BeginInvoke((ThreadStart)delegate ()
            //{
            //    _ = SetStore();
            //});

            //Dispatcher.BeginInvoke(new Action(TestStuff));


            _ = SetStore();

        }

        [ComImport]
        [Guid("4AEEEC08-7C92-4456-A0D6-1B675C7AC005")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IInitializeWithWindow
        {
            void Initialize(IntPtr hwnd);
        }


        private async Task SetStore()
        {
            try
            {
                StoreContext theStore = StoreContext.GetDefault();

                // "Unable to cast object of type 'Windows.Services.Store.StoreContext' to type 'IInitializeWithWindow'."
                // IInitializeWithWindow initWindow = (IInitializeWithWindow)(object)theStore;
                // initWindow.Initialize(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);

                StoreProductResult app = await theStore.GetStoreProductForCurrentAppAsync();

                // This works...
                StoreProduct product = app.Product;
                string title = product.Title;
                string price = product.Price.FormattedPrice;

                // This works...
                StoreAppLicense license = await theStore.GetAppLicenseAsync();
                bool trial = license.IsTrial;
                bool full = license.IsActive;

                // "Invalid window handle.\r\n\r\nThis function must be called from a UI thread" 
                StorePurchaseResult result = await theStore.RequestPurchaseAsync("9NRFBVGVGW8K");


                // "Invalid window handle.\r\n\r\nThis function must be called from a UI thread" 
                // Windows.Foundation.IAsyncOperation<StorePurchaseResult> purchase = product.RequestPurchaseAsync();
            }
            catch (Exception e)
            {
                int a = 1;
            }

        }

I have associated the VS2019 UWP installer project with the store, which I figure is why the other methods return the right answers without needing to cast the store object with IInitializeWithWindow (which also throws an error, but which bypassing seems to let the code work).我已将 VS2019 UWP 安装程序项目与商店相关联,我认为这就是为什么其他方法无需使用 IInitializeWithWindow 转换商店 object 即可返回正确答案的原因(这也会引发错误,但绕过它似乎可以让代码工作) .

I figure I have to tap into the UI thread somehow - go no idea how.我想我必须以某种方式进入 UI 线程 - go 不知道如何。 Various examples from all over the place don't seem to work for me.来自各地的各种例子似乎对我不起作用。 Can anyone help me?谁能帮我?

EDIT: This is a.Net program with a UWP wrapper creating a MSIX package.编辑:这是一个 .Net 程序,带有 UWP 包装器,创建 MSIX package。

For UWP, you need to use the following bit of code to call to the UI thread:对于 UWP,您需要使用以下代码调用 UI 线程:

await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
    //UI code here
});

Try following, It works for me for .net 6 wpf app尝试以下,它适用于 .net 6 wpf 应用程序

WinRT.Interop.InitializeWithWindow.Initialize(storeContext, new WindowInteropHelper(window).Handle);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM