60

我知道这个问题已被问到,至少here什么是编组?什么时候发生什么事情“被编组?”?

但没有一个令人满意的答案,至少不是我。关于与非托管代码进行交互操作,编组有很多讨论,但是从一个线程到另一个线程的编组又如何呢,有时我们必须在.NET中进行编组。

这让我问,什么是编组,真的吗?当你给出编组的定义时,你如何定义它,以便解释互操作性的情况,以及在线程之间“编组”的情况?

+2

你刚刚获得更多的东西已经在那个线程。这是不可避免的,这是一个非常通用的术语。除了“更改运行时环境”之外,并不意味着什么。 – 2011-04-08 21:33:48

回答

72

计算经常需要将数据从一个站点移动到另一个站点,并且没有任何共享内存。所以一个计算会发送一个包含数据的消息给另一个。

该数据如果任意复杂,应该如何在消息中发送?

编组站是数据字段,或整个组相关结构的,转换成可以在一个消息中发送一个连续字符串的过程。要编组二进制 数字,如果消息格式必须是文本,可以将其转换为十六进制数字字符串。如果消息将携带二进制数据,则二进制数可能会转换为4个小端规范化的二进制字节并以此方式发送。指针更难;经常必须将它们转换成独立于实际存储位置的抽象参考(例如“节点号”)。

当然,如果你“马歇尔”的数据,则必须最终“和解组”,这是读取串行流并重建所发送的数据(结构)的过程。

库中常常会有(un)编组例程用于实现此目的,有时甚至有工具会制作(un)编组例程发送/接收数据所需的所有调用。

+4

+1上的序列化细分。 – Alex 2011-04-08 21:22:54

+9

Marhsalling并不一定意味着转换为字符串,尽管.. – 2011-04-08 21:23:56

+17

Copsey是正确的:一般来说,编组用于描述通常从一种语言的一次计算中的数据结构表示转换为一种通用表示形式到另一个计算,可能以不同的表示。即使在同一个过程中,跨语言调用可能需要编组来在它们之间移动数据。我向里德的答复提供了一个意见,供他澄清。 – 2011-04-08 21:30:03

1

它通常用于“用XML格式编写”的上下文中,但它可以编组为任何格式。

2. To arrange, place, or set in methodical order. 
    (from American Heritage® Dictionary of the English Language) 

所以这意味着你正在按照你想要的方式顺序/格式排列数据。通常这是XML格式。

4

我明白编组的方式是,它为您提供了以一致的方式在不同操作环境的数据传输方式。

在将数据从托管代码封装到非托管代码的上下文中,它或多或少是相同的。

我有一些数据,说一个整数数组或我选择的任何数据类型,我想我的C后,使其可使用我的C#代码中++代码做一些关于它的操作。

我不能随便说“嘿,这就是数组是,做你想做什么”的C#代码。 C++中的整数数组可能无法以与C#中相同的方式存储。编组让我们以独立于环境的方式传输这些数据,以便任何一方都能以相同的方式查看数据。

另一个例子是网络。你通常不会调用这个封送处理,但是如果你想通过网络传输它,你通常必须传输它,以便接收它的任何人都可以像你那样解释数据。您的计算机可以以小端顺序表示数据,另一端可以按大端顺序表示。

TL; DR:编组为您提供一种方法来始终代表在各种操作环境数据

24

编组正在数据,某种形式的,并将其转换为一个单独的表格。这是一个非常通用的术语,用在许多意义细微差异的地方。例如,在.NET中,当您使用本机类型时,互操作层将来自.NET类型的数据“编组”成“适当”形式,以调用本机方法,然后将结果“编组”。

至于线程之间的“编组” - 通常情况下,你需要有一些代码,以在不同的线程比当前运行。例如,如果您使用的是Windows窗体,则无法更改线程池线程上的UI元素,因此您需要将该调用“编组”回调到UI线程。这是通过创建一个委托并通过Control.Invoke将委托传递回用户界面线程来完成的(它使用一个相当复杂的系统将其返回到正确的同步上下文),然后在用户界面上运行委托为你穿线。

11

Wikipedia's定义实际上是相当不错的。

编组的整体概念与“序列化:”从内存中表示(从某种意义上说,根本没有表示 - 当内存中的某个东西只是“存在”)向一个“硬拷贝”表示,不管是XML还是二进制流等等。然而,根据你在做什么,它也可能意味着某种转换或翻译成目标格式。

对于过程编组:一个线程并不是简单地“叫”另一个 - 数据必须被包装起来,“已发送”从一个线程到另一个。编组是将数据打包的过程(例如,有关您要调用的方法的数据及其参数)。

如果你在互操作方面编组,要打包了一个方法调用和它的参数转换成可以被发送到正在运行的COM组件进程/线程的数据结构。该包需要采用COM组件可以理解的格式。

3

Wikipedia - Marshalling (computer science)来自:

编组(类似序列化)是变换对象的内存中的表示为适合于存储或传输的数据格式的过程。通常用于必须在计算机程序的不同部分之间或从一个程序到另一个程序之间移动数据的情况。

在.NET中调用非托管函数的情况下,编组用于将.NET数据转换为非托管函数可以使用的数据。例如,System.String是基于Unicode的,但该字符串可能需要转换为ANSI字符串才能传递到非托管C函数。

对于螺纹,典型地编组是指从一个线程传送一些数据的所有权的另一螺纹。例如,一个程序有两个线程。第一个线程从网络读取数据,第二个线程计算该数据。在网络线程读取一些数据之后,它将数据传送(即“编组”)到计算线程以进行处理。它可以通过将数据写入两个线程之间共享的队列来实现。

编组在穿线几乎总是涉及被编组的数据的同步。