.NET核心不支持BeginInvoke? (PlatformNotSupported异常)

时间:2017-07-19 07:09:34

标签: c# asynchronous cross-platform .net-core

我已将库FluentFTP移植到.NET标准/ .NET内核,但异步方法在async / await块中使用BeginInvoke。所以它是这样的:

async ConnectAsync(){
   BeginConnect();
}
void BeginConnect(){
   BeginInvoke(...)   << error at this point
}

此时我得到一个PlatformNotSupported异常。在.NET核心上可以做些什么来支持它?

2 个答案:

答案 0 :(得分:7)

异步I / O方法不应使用Delegate.BeginInvoke。这为一个应该首先应该是异步的同步方法暴露了fake-asynchronous wrapper。整个设计需要重新评估。

.NET Core does not support Delegate.BeginInvoke有很好的理由。 .NET Core 2.0可能决定支持它们(因为Microsoft IMO正在使用v2做出一些糟糕的设计决策)。

但回到最初的问题:解决方案是do the //TODO:实现ConnectAsync作为真正的异步方法。然后,将BeginConnectEndConnect作为ConnectAsync的包装器实现非常简单。

答案 1 :(得分:2)

如@Steven Cleary所述,实现“真正的”异步方法的动机很明显,但是有时候您拥有旧代码,您不能简单地进行异步。对于那些迫切需要保留旧界面的用户:使用Task.Run。例如。

IAsyncResult ar = someDelegate.BeginInvoke(state, null, null);

并使用ar的属性来查看任务何时完成,您很幸运,因为与Tasks等效的是:

Task task = Task.Run(() => someDelegate(state));

好消息是Task类实现了IAsyncResult,因此您可以回收现有代码。 稍后,当您知道代表已经结束时,您可能会打电话给

someDelegate.EndInvoke();

.NET Core都不支持。可以替换为

task.Wait();

它最终会引发您的委托引发的异常,就像EndInvoke一样。 这在我们向.NET Core的迁移中起作用。