【问题标题】:BeginInvoke not supported on .NET core? (PlatformNotSupported exception).NET 核心不支持 BeginInvoke? (PlatformNotSupported 异常)
【发布时间】:2017-07-19 07:09:34
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    异步 ​​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 的包装器非常简单。

    【讨论】:

      【解决方案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 的迁移中奏效。

      【讨论】:

        猜你喜欢
        • 2017-11-24
        • 2019-05-20
        • 2017-07-16
        • 1970-01-01
        • 1970-01-01
        • 2021-02-28
        • 2018-07-06
        • 1970-01-01
        相关资源
        最近更新 更多