gpt4 book ai didi

c# - 来自异步序列化操作的 MissingMethodException

转载 作者:行者123 更新时间:2023-11-30 13:01:45 28 4
gpt4 key购买 nike

我已经为 Json.Net 编写了一个小型异步库包装器来自 NuGet 的 v5.06,在更新了一些 Telerik 包之后,我的 UnitTests 开始失败并显示 MissingMethodException .

我创建了一个有效的虚拟非异步方法,所以我对错误所在感到困惑。

项目目标平台

.Net 4.5

x86 处理器

异步操作

    public class JsonSerialiser : ISerialiser
{

[InjectionConstructor]
public JsonSerialiser(IStringCompression streamCompressor, ILog logger)
{
if (streamCompressor == null) throw new ArgumentNullException("streamCompressor");
if (logger == null) throw new ArgumentNullException("logger");

XmlConfigurator.Configure();

this.streamCompressor = streamCompressor;
this.logger = logger;
}


public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class
{
if (serialseObject == null) throw new ArgumentNullException("serialseObject");

try
{
return await JsonConvert.SerializeObjectAsync(serialseObject);
}
catch (JsonSerializationException ex)
{
logger.Error(ex);
throw new SerialisationException("Could Not Serialse The Object", ex);
}
}
}

异步示例

现在将这段代码放在一起只是为了测试基本序列化,我在类构造函数中跳过空检查。

    private async void button1_Click(object sender, EventArgs e)
{
List<Part> parts = new List<Part> { new Part() { AbstractType = typeof(IOpcController), ConcreteType = typeof(OpcController) },
new Part() { AbstractType = typeof(ISerialiser), ConcreteType = typeof(JsonSerialiser) },
new Part() { AbstractType = typeof(IStringCompression), ConcreteType = typeof(StringGZipCompression)}};

string serialisedResult = string.Empty;
JsonSerialiser serialiser = new JsonSerialiser(null, null);
serialisedResult = await serialiser.SerialiseAsync<List<Part>>(parts);
}

异步结果

这生成一个MissingMethodException

enter image description here

Method not found: 'System.Threading.Tasks.Task`1<System.String> Newtonsoft.Json.JsonConvert.SerializeObjectAsync(System.Object)'.

at Helper.Core.Serialisation.Json.JsonSerialiser.<SerialiseAsync>d__0`1.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine)
at Helper.Core.Serialisation.Json.JsonSerialiser.SerialiseAsync[T](T serialseObject)
at OpcTester.Form1.<button1_Click>d__9.MoveNext() in c:\Users\phil.murray\Desktop\tmp\OpcTester\Form1.cs:line 44

无异步操作

只是为了检查是否是导致问题的方法的异步部分,我编写了一个非异步实现。

public string Serialise<T>(T serialseObject) where T : class
{
if (serialseObject == null) throw new ArgumentNullException("serialseObject");

try
{
return JsonConvert.SerializeObject(serialseObject);
}
catch (JsonSerializationException ex)
{
logger.Error(ex);
throw new SerialisationException("Could Not Serialse The Object", ex);
}
}

无异步实现

private async void button1_Click(object sender, EventArgs e)
{
List<Part> parts = new List<Part> { new Part() { AbstractType = typeof(IOpcController), ConcreteType = typeof(OpcController) },
new Part() { AbstractType = typeof(ISerialiser), ConcreteType = typeof(JsonSerialiser) },
new Part() { AbstractType = typeof(IStringCompression), ConcreteType = typeof(StringGZipCompression)}};

string serialisedResult = string.Empty;
JsonSerialiser serialiser = new JsonSerialiser(null, null);
serialisedResult = serialiser.Serialise<List<Part>>(parts);
}

无异步结果

该方法完成列表并将其序列化为字符串。

失败的测试示例

    Test Name:  SerialiserSerialiseObjectExists
Test FullName: Helper.Tests.SerialiserTests.SerialiserSerialiseObjectExists
Test Source: c:\Perforce\Development\SharedAPIs\Helper.Core\Helper.Tests\SerialiserTests.cs : line 38
Test Outcome: Failed
Test Duration: 0:00:00.0116216

Result Message:
Test method Helper.Tests.SerialiserTests.SerialiserSerialiseObjectExists threw exception:
System.MissingMethodException: Method not found: 'System.Threading.Tasks.Task`1<System.String> Newtonsoft.Json.JsonConvert.SerializeObjectAsync(System.Object)'.
Result StackTrace:
at Helper.Core.Serialisation.Json.JsonSerialiser.<SerialiseAsync>d__0`1.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
a

t System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine)
at Helper.Core.Serialisation.Json.JsonSerialiser.SerialiseAsync[T](T serialseObject)
at Helper.Tests.SerialiserTests.<SerialiserSerialiseObjectExists>d__3.MoveNext() in c:\Perforce\Development\SharedAPIs\Helper.Core\Helper.Tests\SerialiserTests.cs:line 40
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

没有 Json.Net 的异步测试

为了论证,我用虚拟任务替换了 Json.Net 调用并且它起作用了,所以看起来问题出在使用 Await\Async 调用 Json.net。很奇怪,因为它正在运行并且版本尚未更新。

public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class
{
if (serialseObject == null) throw new ArgumentNullException("serialseObject");

try
{
//return await JsonConvert.SerializeObjectAsync(serialseObject);
return await Task.Run(() => string.Empty);
}
catch (JsonSerializationException ex)
{
logger.Error(ex);
throw new SerialisationException("Could Not Serialse The Object", ex);
}
}

问题

现在,在我更新 Telerik 控件套件之前,异步方法 UnitTests 之前可以正常工作,并且我确实在许多真实世界的实例中测试了该操作。我并不是说 Telerik 更新导致了问题,因为这可能是巧合。在测试其他类(与 Json.Net 无关)时,许多其他异步测试用例通过。

知道异步方法有什么问题以及如何解决该问题吗?

可能的解决方案

当我继续调查这个问题时,我发现问题可能出在 Json.Net 库中的异步调用中,所以我将 none 异步调用包装在一个任务中,如下所示,它起作用了

    public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class
{
if (serialseObject == null) throw new ArgumentNullException("serialseObject");

try
{
//return await JsonConvert.SerializeObjectAsync(serialseObject);
return await Task.Run<string>(() => JsonConvert.SerializeObject(serialseObject));
}
catch (JsonSerializationException ex)
{
logger.Error(ex);
throw new SerialisationException("Could Not Serialse The Object", ex);
}
}

出于兴趣,我下载了 Json.Net 的源代码并检查了 JsonConvert.SerializeObjectAsync 调用,它在做同样的事情,所以我再次不确定潜在的问题。

public static Task<string> SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings)
{
return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings));
}

最佳答案

检查包含您正在执行的程序集的输出目录。在 Newtonsoft.Json.dll 属性中,您会看到描述为“Json.Net Portable .Net 4.0”,并且此版本不提供 SerializeObjectAsync(您可以使用 ILSpy 检查程序集)。

enter image description here

用 .Net 4.5 版本替换 Json 程序集,它应该可以工作。

关于c# - 来自异步序列化操作的 MissingMethodException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17921437/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com