Rob*_*cks 7 c# asynchronous cross-platform .net-core
我已将库FluentFTP移植到.NET标准/ .NET内核,但异步方法在async/await块中使用BeginInvoke.它是这样的:
async ConnectAsync(){
BeginConnect();
}
void BeginConnect(){
BeginInvoke(...) << error at this point
}
Run Code Online (Sandbox Code Playgroud)
那时我得到一个PlatformNotSupported异常.在.NET核心上可以做些什么来支持它?
JSp*_*pot 17
正如@Steven_Cleary 所述,实现“真正”异步方法的动机很明确,但有时您有遗留代码,不能简单地进行异步。对于那些迫切需要保留旧界面的人:使用Task.Run. 例如,当你有
IAsyncResult ar = someDelegate.BeginInvoke(state, null, null);
Run Code Online (Sandbox Code Playgroud)
并使用属性ar来查看任务何时完成,您很幸运,因为任务的等效项是:
Task task = Task.Run(() => someDelegate(state));
Run Code Online (Sandbox Code Playgroud)
好消息是Task该类实现IAsyncResult了您可以回收现有代码。稍后当您知道委托已完成时,您可能会调用
someDelegate.EndInvoke();
Run Code Online (Sandbox Code Playgroud)
.NET Core 都不支持。这可以替换为
task.Wait();
Run Code Online (Sandbox Code Playgroud)
它最终会抛出您的委托抛出的异常,就像EndInvoke. 这在我们迁移到 .NET Core 时起作用。
不应使用异步I/O方法Delegate.BeginInvoke.这暴露了一个同步方法的假异步包装器,它应该首先是异步的.整个设计需要重新评估.
.NET Core不支持Delegate.BeginInvoke非常好的理由..NET Core 2.0可能决定支持它们(因为Microsoft IMO正在使用v2做出一些糟糕的设计决策).
但回到最初的问题:解决方案是执行//TODO:实现ConnectAsync为真正的异步方法.然后它非常简单地实现BeginConnect并EndConnect作为包装器ConnectAsync.