抛出异常:UWP 后台任务中未知模块中的 'System.TypeLoadException'
Exception thrown: 'System.TypeLoadException' in Unknown Module in UWP Background Task
这段代码给了我例外
Exception thrown: 'System.TypeLoadException' in Unknown Module
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 Background Task做async好不好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()
中,它就无法解决上述错误。
这个解决方案没有帮助
谢谢!
我稍微简化了解决方案并删除了 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;
}
}
这段代码给了我例外
Exception thrown: 'System.TypeLoadException' in Unknown Module
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 Background Task做async好不好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()
中,它就无法解决上述错误。
这个解决方案没有帮助
谢谢!
我稍微简化了解决方案并删除了 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;
}
}