Возникло исключение: System.TypeLoadException в неизвестном модуле в фоновой задаче UWP - PullRequest
0 голосов
/ 19 февраля 2019

Этот код дает мне исключение

Исключение: 'System.TypeLoadException' в неизвестном модуле

public sealed class SampleBackgroundTask2 : IBackgroundTask
{

        EasClientDeviceInformation currentDeviceInfo;

        BackgroundTaskCancellationReason _cancelReason = BackgroundTaskCancellationReason.Abort;

        BackgroundTaskDeferral _deferral = null;

        IBackgroundTaskInstance _taskInstance = null;

        ThreadPoolTimer _periodicTimer = null;

        //
        // The Run method is the entry point of a background task.
        //
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            currentDeviceInfo = new EasClientDeviceInformation();

            var cost = BackgroundWorkCost.CurrentBackgroundWorkCost;
            var settings = ApplicationData.Current.LocalSettings;
            settings.Values["BackgroundWorkCost2"] = cost.ToString();

            taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);

            _deferral = taskInstance.GetDeferral();
            _taskInstance = taskInstance;

            _periodicTimer = ThreadPoolTimer.CreateTimer(new TimerElapsedHandler(PeriodicTimerCallbackAsync), TimeSpan.FromSeconds(1));
        }

        private async void PeriodicTimerCallbackAsync(ThreadPoolTimer timer)
        {
            try
            {
                var httpClient = new HttpClient(new HttpClientHandler()); 

                string urlPath = (string)ApplicationData.Current.LocalSettings.Values["ServerIPAddress"] + "/Api/Version1/IsUpdatePersonal";

                HttpResponseMessage response = await httpClient.PostAsync(urlPath,
                    new StringContent(JsonConvert.SerializeObject(currentDeviceInfo.Id.ToString()), Encoding.UTF8, "application/json")); // new FormUrlEncodedContent(values)

                response.EnsureSuccessStatusCode();

                if (response.IsSuccessStatusCode)
                {
                    string jsonText = await response.Content.ReadAsStringAsync();
                    var customObj = JsonConvert.DeserializeObject<bool>(jsonText, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });

                    if (customObj) // Если TRUE  то да надо сообщить пользователю о необходимости обновления
                    {
                        ShowToastNotification("Ttitle", "Message");
                    }
                }
            }
            catch (HttpRequestException ex)
            {
            }
            catch (Exception ex)
            {
            }
            finally
            {
                _periodicTimer.Cancel();
                _deferral.Complete();
            }
        }

private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            _cancelReason = reason;
        }
}

Если я комментирую места async / await и HttpClientтогда нет исключения.

Так что не так с моим кодом?Или все-таки хорошо использовать фоновую задачу UWP для создания асинхронного GET / POST?

Я пробовал какое-то классическое решение, например

public async void Run(IBackgroundTaskInstance taskInstance)
{
 BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
 //
 // Start one (or more) async
 // Use the await keyword
 //
 // await SomeMethodAsync();


        var uri = new System.Uri("http://www.bing.com");
        using (var httpClient = new Windows.Web.Http.HttpClient())
        {
            // Always catch network exceptions for async methods
            try
            {
                string result = await httpClient.GetStringAsync(uri);
            }
            catch (Exception ex)
            {
                // Details in ex.Message and ex.HResult.
            }
        }


 _deferral.Complete();
}

, но как только я поместил HttpClient внутри SomeMethodAsync() это не работает с ошибкой выше.

Это решение не помогает Сбой HttpClient.GetAsync в фоновой задаче с доступом к экрану блокировки и TimeTrigger или MaintenanceTrigger

Спасибо!

1 Ответ

0 голосов
/ 20 февраля 2019

Я немного упростил решение и удалил ThreadPoolTimer, так как я не был уверен, почему оно использовалось из кода.Пожалуйста, укажите, требуется ли оно для решения.

Если ThreadPoolTimer не является обязательным, вы можете попробовать следующий код:

public sealed class SampleBackgroundTask2 : IBackgroundTask
    {

        EasClientDeviceInformation currentDeviceInfo;

        BackgroundTaskCancellationReason _cancelReason = BackgroundTaskCancellationReason.Abort;

        BackgroundTaskDeferral _deferral = null;

        //
        // The Run method is the entry point of a background task.
        //
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            currentDeviceInfo = new EasClientDeviceInformation();

            var cost = BackgroundWorkCost.CurrentBackgroundWorkCost;
            var settings = ApplicationData.Current.LocalSettings;
            settings.Values["BackgroundWorkCost2"] = cost.ToString();

            taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);

            _deferral = taskInstance.GetDeferral();
            await asynchronousAPICall();
            _deferral.Complete(); //calling this only when the API call is complete and the toast notification is shown
        }
        private async Task asynchronousAPICall()
        {
            try
            {
                var httpClient = new HttpClient(new HttpClientHandler());

                string urlPath = (string)ApplicationData.Current.LocalSettings.Values["ServerIPAddress"] + "/Api/Version1/IsUpdatePersonal";

                HttpResponseMessage response = await httpClient.PostAsync(urlPath,
                    new StringContent(JsonConvert.SerializeObject(currentDeviceInfo.Id.ToString()), Encoding.UTF8, "application/json")); // new FormUrlEncodedContent(values)

                response.EnsureSuccessStatusCode();

                if (response.IsSuccessStatusCode)
                {
                    string jsonText = await response.Content.ReadAsStringAsync();
                    var customObj = JsonConvert.DeserializeObject<bool>(jsonText, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });

                    if (customObj) // Если TRUE  то да надо сообщить пользователю о необходимости обновления
                    {
                        ShowToastNotification("Ttitle", "Message");
                    }
                }
            }
            catch (HttpRequestException ex)
            {
            }
            catch (Exception ex)
            {
            }
            finally
            {
                _deferral.Complete();
            }
        }

        private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            _cancelReason = reason;
        }
    }

Пожалуйста, дайте мне знать, если это работает для вас.

...