【发布时间】:2015-10-13 02:16:48
【问题描述】:
所以我为我的客户制作了一个请求包装器,一切正常。但是突然(我不知道为什么)JsonConvert.DeserializeObject<T>(c) 抛出了经典异常
调用线程无法访问此对象,因为不同的线程拥有它
嗯,除了这个,我没有看到任何其他线程。它们都是局部变量,根据 Newtonsoft https://github.com/JamesNK/Newtonsoft.Json/issues/469
每次反序列化对象时都会创建一个新的 JsonSerializerInternalReader
你知道这个异常所说的另一个线程在哪里吗?
public static Task<Response<T>> _reqWrapper<T>(Func<Task<HttpResponseMessage>> request)
where T : class
{
return Task.Run(async () =>
{
var response = new Response<T>();
var hrm = await request().ConfigureAwait(false);
var c = await hrm.Content.ReadAsStringAsync().ConfigureAwait(false);
response.Content = JsonConvert.DeserializeObject<T>(c);
return response;
});
已经尝试过,但运气不佳。
response.Content = await Task.Run(() => JsonConvert.DeserializeObject<T>(c));
更新
为了确保那条线是我做的那条线:
T t = null;
try
{
t = JsonConvert.DeserializeObject<T>(c);
}
catch { }
response.Content = t
一切都运行良好。有什么线索吗?
更新 2
堆栈跟踪
我在这里看到的是序列化程序正在尝试访问主窗口。我不得不说这是在ShowDialog() 窗口内发生的,所以我猜主窗口不可用。但我不确定我是否正确或如何解决此问题。
在 System.Windows.Threading.Dispatcher.VerifyAccess() 在 System.Windows.Application.get_MainWindow() 在 C:... 中的 ControliWindows.Globals.Controli.get_Window() 在 ControliWindows.Globals.Framework.Modalizer.SaveableModel1..ctor() 在 C:... 在 C:... 中的 ControliWindows.Views.Modals.AccountMm..ctor() 在 CreateControliWindows.Views.Modals.AccountMm() 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader 阅读器,JsonObjectContract objectContract,JsonProperty containerMember,JsonProperty containerProperty,String id,Boolean& createdFromNonDefaultCreator) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader 阅读器,类型 objectType,JsonContract 合同,JsonProperty 成员,JsonContainerContract containerContract,JsonProperty containerMember,对象现有值) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader 阅读器,类型 objectType,JsonContract 合同,JsonProperty 成员,JsonContainerContract containerContract,JsonProperty containerMember,对象现有值) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader 阅读器,类型 objectType,布尔 checkAdditionalContent) 在 Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader 阅读器,类型 objectType) 在 Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader 阅读器,类型 objectType) 在 Newtonsoft.Json.JsonConvert.DeserializeObject(字符串值,类型类型,JsonSerializerSettings 设置) 在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](字符串值,JsonSerializerSettings 设置) 在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](字符串值) 在 ControliWindows.Globals.Connection.c__DisplayClass39_0`1.b__0>d.MoveNext() in C:...
【问题讨论】:
-
一旦你等待某事,一旦你恢复,你很可能在不同的线程上运行。不知道为什么在这种情况下这很重要。
-
试试不带
ConfigureAwait(false)。 -
@bto.rdz 请发布您的整个代码,因为它几乎肯定与您上面的 sn-p 无关。在某个地方,会有一段代码与 UI 组件交互。至少,您的
PostAsync上发生了异常,这意味着您发布的响应代码甚至还没有执行。 -
@EricJ。通常
await之后的代码将在 WinForms/WPF/ASP.Net 的原始线程上运行...实际上在 OP 的代码中并非如此,因为它们明确要求不要回到原始线程(两次)-一次使用 @987654330 @ 并且绝对确定ConfigureAwait(false)... -
我认为Task.Run 等从这里的图片中消失 - 只是等待事情而不使用 ConfigureAwait(false)。那时您不会切换到其他逻辑调用上下文,也许一切都会好起来的。如果您确实需要启动一个单独的线程,从而让事情真正并行运行(而不是允许通过 async/await 进行重叠响应),请轻轻引入它,看看是什么导致您的失败返回。
标签: c# multithreading json.net async-await httpclient