c# – JsonConvert.DeserializeObject和ThreadAbortedException
在Xamarin项目中,我有以下代码的PCL库.
我们定义ConcurrentQueue< SyncRequest>.对于初始化对象初始化,已附加了使用者任务: _syncConsumer = new Task( ProcessSyncQueue,_syncConsumerCancellationTokenSource.Token); _syncConsumer.Start(); ProcessSyncQueue方法扫描同步队列并调用GetSyncableEntity方法: private async void ProcessSyncQueue() { while (true) { SyncRequest syncRequest; if (_syncQueue.TryDequeue(out syncRequest)) { var syncableEntity = GetSyncableEntity(syncRequest); } } } GetSyncableEntity依次执行Json反序列化: private T GetSyncableEntity(SyncRequest syncRequest) { T syncableEntity = default(T); try { syncableEntity = JsonConvert.DeserializeObject<T>(syncRequest.SynchronizationContent); } catch (Exception e) { } return syncableEntity; } 在这一步中,我们收到ThreadAbortedException,其中包含’Thread was aborted’消息. at Newtonsoft.Json.JsonTextReader.FinishReadStringIntoBuffer(Int32 charPos,Int32 initialPosition,Int32 lastWritePosition) at Newtonsoft.Json.JsonTextReader.ReadStringIntoBuffer(Char quote) at Newtonsoft.Json.JsonTextReader.ParseProperty() at Newtonsoft.Json.JsonTextReader.ParSEObject() at Newtonsoft.Json.JsonTextReader.Read() at Newtonsoft.Json.JsonReader.ReadAndAssert() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader,Type objectType,JsonContract contract,JsonProperty member,JsonContainerContract containerContract,JsonProperty containerMember,Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader,Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader,Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader,Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value,Type type,JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value,JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value) 任何人都可以帮助我们了解发生了什么以及如何反序列化? 更新: protected void RequestSynchronizationFor( string synchronizationKey,T entity) { if (!_isInitialized) { InitializeSyncRequestsQueue(); } _syncQueue.Enqueue(GetSyncRequest(synchronizationKey,entity)); } 所以我们请求实体同步调用RequestSynchronizationFor方法.如果是冷运行,我们从db调用InitializeSyncRequestsQueue并等待Task.Run使用者线程初始化队列. private async void InitializeSyncRequestsQueue() { var syncRequests = GetSyncedRequests(); foreach (var syncRequest in syncRequests) { _syncQueue.Enqueue(syncRequest); } await Task.Run(ProcessSyncQueue); } 像以前一样的消费者任务做同样的事情: private async Task ProcessSyncQueue() { while (true) { SyncRequest syncRequest; if (_syncQueue.TryDequeue(out syncRequest)) { var syncableEntity = GetSyncableEntity(syncRequest); } } } 仍然有同样的例外.不确定它是否合理,但我正在运行单元测试中的代码.有什么建议? UPDATE2: 在我做了更改后,我在第一个’UPDATE’中发布了,调用堆栈也发生了一些变化: at Newtonsoft.Json.JsonSerializer.get_MetadataPropertyHandling() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader,JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value) 更新3: public class JsonDeserializeService<T> { private readonly bool _isInitialized; private readonly ConcurrentQueue<SyncRequest> _syncQueue; public JsonDeserializeService() { _isInitialized = false; _syncQueue = new ConcurrentQueue<SyncRequest>(); } public void RequestSynchronizationFor( string synchronizationKey,entity)); } private async void InitializeSyncRequestsQueue() { var syncRequests = Enumerable.Empty<SyncRequest>(); foreach (var syncRequest in syncRequests) { _syncQueue.Enqueue(syncRequest); } await Task.Run(ProcessSyncQueue); } private async Task ProcessSyncQueue() { while (true) { SyncRequest syncRequest; if (_syncQueue.TryDequeue(out syncRequest)) { var syncableEntity = GetSyncableEntity(syncRequest); } } } private T GetSyncableEntity(SyncRequest syncRequest) { T syncableEntity = default(T); try { syncableEntity = JsonConvert.DeserializeObject<T>(syncRequest.SynchronizationContent); } catch (Exception e) { } return syncableEntity; } private SyncRequest GetSyncRequest(string synchronizationKey,T entity) { return new SyncRequest() { SynchronizationContent = JsonConvert.SerializeObject(entity),SynchronizationDelayUntil = DateTime.Now }; } } 从单元测试触发: public void Syncable_Service_Should_Not_Generate_Exception() { var syncService = new JsonDeserializeService<FakeSyncableEntity>(); syncService.RequestSynchronizationFor("syncKey",new FakeSyncableEntity() { Content = "Content" }); } 解决方法
这种行为的原因很简单.
您的测试比异步任务更早结束.当测试结束时,它会为子线程引发ThreadAbortException. 您需要调用task.Wait()以使主线程等待任务完成. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- PostgreSQL的 pg_hba.conf 文件简析
- ios – Appcode – 选择当前文件
- 关于Oracle的PARALLEL_MAX_SEVERS参数
- objective-c – iOS:在ImageView上绘制一个矩形并调整边框
- c – 尝试在缺少依赖DLL时使用LoadLibrary在Windows上加载D
- 除了RSL,Flex框架底层还会默认加载些什么?
- flex 学习总结
- ruby-on-rails – 从Rails应用程序(Word,PDF,Excel等)搜索附
- c# – 是否有一种简单的方法可以将数字转换为印度语单词格式
- React学习(8)—— 高阶应用:不使用ES6、JSX实现React