2014-05-14 84 views
2

我有服务和WinForm应用程序之间的IPC通信。他们互通与类的帮助下,利用以下接口:通过任务<T>通过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切换到任务时,我在Assembly'mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken =中得到一个异常类型'System.Threading.Tasks.Task`1 [[IPCInfo] b77a5c561934e089'未标记为可序列化。 我看到它试图序列化任务并失败。有没有解决这个问题的方法?

+0

将kruoli的答案转换为注释:*可能[此链接](http://blogs.msdn.com/b/lucian/archive/2012/11/24/how-to-hibernate-async-methods-how -to-serialize-task.aspx)是一个很好的解释。* – hyde

回答

4

以什么二进制格式发送任务?这个问题没有合理的答案。因此,您无法发送任务。说得通?

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

您可能在这里处理sync-over-async的情况。阅读并理解这一点。您现在会意识到您的状况不佳。你会得到两个世界中最糟糕的结果:没有异步IO优势和更多的CPU使用率。

该怎么办?取决于你的申请。也许你不应该异步(因为框架不支持它)。

+0

我正在使用System.Runtime.Remoting。我正在制作一个UI来控制服务,该服务执行长时间运行的操作,例如与远程服务器通信。最简单的方法是在UI端封装同步调用,但这意味着我将不得不第三次复制相同的代码,因为控制类看起来像这样:[Serializable] public class ServiceControl:MarshalByRefObject, IBaseIPC 公共静态IBaseIPC客户端; public Task GetConfig() return client.GetConfig(); } ...} – KorsaR

+0

AFAIK Remoting不支持异步调用。你在那里运气不好。但为什么你需要复制东西?只要你可以在任何地方同步,并使用户界面异步(可能通过用Task.Run包装远程调用,这是一个有效的策略)。 – usr

+0

好吧,Remoting支持异步(http://msdn.microsoft.com/en-us/library/3k559b9a(v=vs.85).aspx),但我不会使用它。与仅在用户界面中使用await Task.Run相比,这很难使用。 – usr