Как вы вызываете метод из потока пользовательского интерфейса? - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь получить доступ к Microsoft Store из многопоточной программы. Сама программа работает хорошо - проблем нет, но метод

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

выдает исключение:

"Недопустимый дескриптор окна. \ R \ n \ r \ nЭта функция должна вызываются из потока пользовательского интерфейса "

Мой код выглядит следующим образом ...

        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;
            }

        }

Я связал проект установщика UWP VS2019 с магазином, который я понимаю, поэтому другие методы возвращают правильные ответы без необходимости приведения объекта хранилища с помощью IInitializeWithWindow (который также выдает ошибку, но обход которого, по-видимому, позволяет коду работать).

Я полагаю, мне нужно подключиться к потоку пользовательского интерфейса как-то - go не знаю как. Различные примеры повсюду не подходят для меня. Кто-нибудь может мне помочь?

РЕДАКТИРОВАТЬ: Это. Net программа с оболочкой UWP создает пакет MSIX.

1 Ответ

0 голосов
/ 24 апреля 2020

Для UWP вам необходимо использовать следующий бит кода для вызова потока пользовательского интерфейса:

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