【问题标题】:Exception thrown: 'System.TypeLoadException' in Unknown Module in UWP Background Task抛出异常:UWP 后台任务中未知模块中的“System.TypeLoadException”
【发布时间】:2019-02-19 05:27:22
【问题描述】:

这段代码给了我异常

抛出异常:未知模块中的“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 fails in background task with lock screen access and both TimeTrigger or MaintenanceTrigger

谢谢!

【问题讨论】:

    标签: c# uwp httpclient background-task


    【解决方案1】:

    我稍微简化了解决方案并删除了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;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2019-04-02
      • 2011-08-22
      • 1970-01-01
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 2012-04-16
      相关资源
      最近更新 更多