【问题标题】:Passing Task<T> via IPC通过 IPC 传递 Task<T>
【发布时间】:2014-05-14 14:02:06
【问题描述】:

我在服务和 WinForm 应用程序之间进行了 IPC 通信。它们在类的帮助下相互通信,该类使用以下接口:

public interface IBaseIPC
{

    Task<IPCConfig> GetConfig();
    Task<IPCInfo> Activate(IPCConfig ipcConfig);
    Task<IPCInfo> CancelActivation();
    Task<IPCInfo> GetInfo();
    Task<IPCInfo> Renew();
    Task<string> TestConnection(IPCConfig ipcConfig);
}

当这些方法同步时,它工作得很好。现在,当返回类型从 IPCConfig 切换到 Task 时,我在程序集 'mscorlib、Version=4.0.0.0、Culture=neutral、PublicKeyToken= b77a5c561934e089' 未标记为可序列化。 我看到它尝试序列化 Task 并失败。有没有办法解决这个问题?

【问题讨论】:

  • 将 kruoli 的答案转换为评论:也许this link 是一个很好的解释。

标签: c# asynchronous ipc


【解决方案1】:

你会以什么二进制格式发送任务?这个问题没有合理的答案。因此,您无法发送任务。有意义吗?

如果您的 IPC 库或框架本质上不是异步的,则您无法将任务返回给它。框架必须理解它们。

您可能正在处理sync-over-async 场景。阅读并理解这一点。你现在会意识到你的处境并不好。你得到了两全其美:没有异步 IO 的好处和更多的 CPU 使用率。

该怎么办?取决于您的应用程序。也许您根本不应该使用异步(因为框架不支持它)。

【讨论】:

  • 我正在使用 System.Runtime.Remoting。我正在制作一个 UI 来控制服务,该服务执行长时间运行的操作,例如与远程服务器通信。最简单的方法是在 UI 端包装同步调用,但这意味着我必须第三次复制相同的代码,因为到目前为止,控件类看起来像这样: [Serializable] public class ServiceControl : MarshalByRefObject, IBaseIPC公共静态 IBaseIPC 客户端;公共任务 GetConfig() { return client.GetConfig(); } ...}
  • AFAIK Remoting 不支持异步调用。你在那里不走运。但是为什么你需要复制东西呢?尽可能同步,并使 UI 异步(可能通过使用 Task.Run 包装远程调用,这是一种有效的策略)。
  • 好的,Remoting 支持异步 (msdn.microsoft.com/en-us/library/3k559b9a(v=vs.85).aspx) 但我不会使用它。与仅在 UI 中使用 await Task.Run 相比,它很难使用。
  • 我复制代码的原因是我在不同的客户端类中实现了这些方法,它们利用了接口,然后我有控制类,我只是去 SomeMethod(){client.SomeMethod( );},现在我必须执行 Task.Run(()=>controlClass.SomeMethod()),所以我想也许有更优雅的方法可以做到这一点。
  • 如果没有更多代码和上下文,我不能推荐任何东西。但我想你现在明白了这个问题。考虑使除 UI 之外的所有内容都同步。或者,使用 WCF。然后你可以做一个同步服务和一个异步客户端。
猜你喜欢
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多