如何在.NET 3.5中通过NamedPipe发送对象?

发布于 2024-07-29 02:39:48 字数 52 浏览 6 评论 0原文

您能告诉我在 .net 3.5 中通过 NamedPipes 发送对象的最佳方式是什么吗?

Can you tell me what's the best way to send objects through NamedPipes in .net 3.5?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

新人笑 2024-08-05 02:39:48

通过 XmlSerializer 序列化您的对象,而不是 将其作为文本发送并在另一个中反序列化侧面,或者按照 Remus 的建议使用 WCF 命名管道绑定

Serialize your object by XmlSerializer than send it as a text and deserialize in the other side, or use WCF named pipes binding as Remus suggests

爱给你人给你 2024-08-05 02:39:48

WCF NetNamedPipes 绑定是可行的方法,您也可以考虑使用 .NET Remoting 来实现此目的

WCF NetNamedPipes binding is the way to go, you might also consider .NET Remoting to achieve this

和影子一齐双人舞 2024-08-05 02:39:48

您正在寻找的是 DataContract 属性。 另请参阅:MSDN 使用数据协定

数据契约是服务和客户端之间的正式协议,它抽象地描述了要交换的数据。 也就是说,为了进行通信,客户端和服务不必共享相同的类型,只需共享相同的数据契约。 数据契约针对每个参数或返回类型精确定义了要交换的数据序列化(转换为 XML)。

您的服务合同:

[ServiceContract]
public interface IApplicationRegistration
{
    // Sends the application information
    [OperationContract]
    bool RegisterApplication(AppInfo appInfo);
}

要交换的数据:

[DataContract]
public class AppInfo
{
    private int _processID;
    private string _processName;

    [DataMember]
    public int ProcessID
    {
        get { return _processID; }
        set { _processID = value; }
    }

    [DataMember]
    public string ProcessName
    {
        get { return _processName; }
        set { _processName= value; }
    }
}

What you are looking for is DataContract attribute. See also: MSDN Using Data Contracts.

A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. A data contract precisely defines, for each parameter or return type, what data is serialized (turned into XML) to be exchanged.

Your service contract:

[ServiceContract]
public interface IApplicationRegistration
{
    // Sends the application information
    [OperationContract]
    bool RegisterApplication(AppInfo appInfo);
}

The data to exchange:

[DataContract]
public class AppInfo
{
    private int _processID;
    private string _processName;

    [DataMember]
    public int ProcessID
    {
        get { return _processID; }
        set { _processID = value; }
    }

    [DataMember]
    public string ProcessName
    {
        get { return _processName; }
        set { _processName= value; }
    }
}
纵山崖 2024-08-05 02:39:48

正如对原始问题的评论指出的那样,您不会将对象发送到其他进程。 您可以将数据发送到另一个进程,并且该数据可用于在另一个进程中创建原始对象的代理或传真,但您不能直接发送对象。

即使是提供进程间对象传递语义的技术,在幕后也正是这样做的。 因此,您应该始终使用“尝试执行操作,如果失败则捕获异常”的操作风格,而不是“确保可以执行该操作然后执行它”的操作风格。 即使该对象看起来对于您的操作来说处于有效状态,但您正在查看旧数据,因此当您尝试执行实际操作时它可能无效。

因此,由于您无法发送对象,因此您最终要做的就是序列化一些数据(使用 XmlSerializer 或 DataContractSerializer 等),读取另一端的数据流,并创建一个新对象来代表旧的。 您可能会发现创建一个单独的对象来表示您希望通过管道发送的数据比创建对象的实际实时表示更容易。

WCF 可以自动为您处理很多这样的事情,但是您自己通过管道发送它并没有什么困难。

如果按照其他人的建议使用 WCF,请注意您仍然没有发送“对象”。 您仍在发送数据,并且 WCF 对此非常明确(这就是为什么他们将其称为 DataContractSerializer,而不是 ObjectSerializer)。 具体来说:

1) 对通过 DataContract 序列化发送的对象执行的任何操作都将在本地执行。

2)如果同一个对象被发送两次,它不会自动更新它的任何旧版本,并且它们不会具有引用相等性。 您将拥有两个数据结构,就 C# 而言,它们是完全不相关的。

3)对一个对象的更新只会在本地执行,并且不会自动更新具有“相同”对象的其他进程。

如果您绝对确信需要跨进程传递“对象”,则可以自行推出(我实际上建议这样做,尽管这需要更多工作),或者使用 System.Remoting 命名空间。

即使使用 System.Remoting,也要认识到我上面讨论的正是实际发生的情况,并在设计对象和系统时考虑到这一点。 你会得到更好的结果。

As a comment on the original question pointed out, you don't send objects to other processes. You can send data to another process, and that data can be used to create a proxy or facsimile of the original object in the other process, but you can't directly send an object.

Even technologies that offer inter-process object-passing semantics are, under the hood, doing exactly that. Because of this, you should always use the 'try to perform an operation, and catch the exception if it fails' style of operations rather than 'make sure it's okay to do the operation and then perform it' style. Even if the object looks like it's in a valid state for your operation, you're looking at old data, and so it may not be valid when you try to perform the actual operation.

So, since you can't send objects, what you're really going to end up doing is serializing some data (using XmlSerializer, or DataContractSerializer, or whatever), reading the data stream on the other end, and creating a new object to represent the old one. You may find it easier to create a separate object to represent the data you wish to send across the pipe, as opposed to the actual, live representation of the object.

WCF can handle a lot of this stuff automagically for you, but there's nothing too difficult about sending it over a pipe yourself.

If using WCF as others have suggested, be aware that you're still not sending "objects." You're still sending data, and WCF is pretty explicit about this (which is why they call it a DataContractSerializer, and not an ObjectSerializer). Specifically:

1) Any operations performed on an object sent with DataContract serialization will be performed locally.

2) If the same object is sent twice, it will not automatically update any old versions of it, and they will not have reference equality. You will have two data structures that, as far as C# is concerned, are entirely unrelated.

3) Updates to an object will only be performed locally, and will not automatically update other processes with the "same" object.

If you're absolutely convinced that you need to pass "objects" across processes, you can either roll your own (which I'd actually recommend, even though it's more work), or use the System.Remoting namespace.

Even if using System.Remoting, realize that what I've talked about above is what is actually happening, and design your objects and system with that in mind. You'll get a lot better results.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文