所以我为我的客户制作了一个请求包装器,一切正常。但突然(我不知道为什么)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(): 在C:中的ControliWindows.Globals.Framework.Modalizer.SaveableModel1..ctor()中... 在C:中的ControliWindows.Views.Modals.AccountMm..ctor(): 在CreateControliWindows.Views.Modals.AccountMm() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader,JsonObjectContract objectContract,JsonProperty containerMember,JsonProperty containerProperty,String id,Boolean&amp; createdFromNonDefaultCreator) 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,Type objectType,JsonContract contract,JsonProperty member,JsonContainerContract containerContract,JsonProperty containerMember,Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader,Type objectType,Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader,Type objectType) 在Newtonsoft.Json.JsonSerializer.Deserialize(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) 在ControliWindows.Globals.Connection。&lt;&gt; c__DisplayClass39_0`1。&lt;&lt; _reqWrapper&gt; b__0&gt; d.MoveNext()在C:...
答案 0 :(得分:2)
在System.Windows.Threading.Dispatcher.VerifyAccess()处于System.Windows.Application.get_MainWindow()的ControliWindows.Globals.Controli.get_Window()位于C:...中的ControliWindows.Globals.Framework.Modalizer。 C中的SaveableModel1..ctor():...在C:...中的ControliWindows.Views.Modals.AccountMm..ctor()
这是你问题的根源。以下是正在发生的一系列事件:
T
是ControliWindows.Views.Modals.AccountMm
而DeserializeObject
必须新建一个AccountMm
的构造函数正在创建ControliWindows.Globals.Framework.Modalizer.SaveableModel1
SaveableModel1
的构造函数正在读取属性ControliWindows.Globals.Controli.Window
Controli.Window
中正在阅读属性System.Windows.Application.Window
Application.Window
只能从UI线程读取,整个事件链发生在Threadpool线程上并导致异常。最简单的解决方案是ControliWindows.Globals.Controli.Window
检测它是否不在UI线程上,如果它没有调用UI来获取Application.Window
的值。
public static class Controli
{
public Window Window
{
get
{
var application = Application.Current;
if(application == null)
return null;
try
{
return application.MainWindow;
}
catch(InvalidOperationException)
{
return application.Dispatcher.Invoke(() => application.MainWindow);
}
}
}
}
答案 1 :(得分:0)
通过使用ConfigureAwait(false)
,您明确告诉等待在执行等待之后不要尝试在同一线程上恢复执行代码。
continueOnCapturedContext
类型:System.Boolean
true 尝试将继续编组回到捕获的原始上下文;否则, false 。
请尝试使用ConfigureAwait(true)
。
答案 2 :(得分:0)
在另一个线程中发生了消毒。它打开自己的线程