我知道这个问题已经被问过了,至少 这里 有讨论。
但是对我来说没有一个令人满意的答案。关于与非托管代码互操作时的marshalling,有很多讨论,但从一个线程到另一个线程的marshalling呢?这在.NET中有时是必须的。
这使我想问,什么是marshalling?当你给出marshalling的定义时,如何定义它以解释互操作性的情况,以及在“marshalling”线程之间的情况?
我知道这个问题已经被问过了,至少 这里 有讨论。
但是对我来说没有一个令人满意的答案。关于与非托管代码互操作时的marshalling,有很多讨论,但从一个线程到另一个线程的marshalling呢?这在.NET中有时是必须的。
这使我想问,什么是marshalling?当你给出marshalling的定义时,如何定义它以解释互操作性的情况,以及在“marshalling”线程之间的情况?
在计算过程中,数据经常需要从一个站点移动到另一个站点,并且没有任何共享的内存。因此,一个计算发送包含数据的消息给另一个计算。
如果这些数据非常复杂,应该如何在消息中发送?
编组是将数据字段或整个相关结构转换为序列化字符串的过程,以便可以在消息中发送。要编组二进制数,可以将其转换为十六进制数字字符串,如果消息格式必须为文本,则采用此方法。如果消息将携带二进制数据,则可以将二进制数转换为4个小端规范化的二进制字节,并以这种方式发送。指针更难处理,通常必须将它们转换为抽象引用(例如,“节点编号”),这些引用与实际的内存位置无关。
当然,如果对数据进行编组,则最终必须进行“解组”,即读取序列流并重建传输的数据(结构)的过程。
通常,在库中有(解)编组例程用于完成此目的,有时甚至有工具可以生成所有所需的(解)编组例程调用来发送/接收数据。
“Marshalling”是将某种形式的数据翻译成另一种形式的过程。它是一个非常通用的术语,在许多地方使用,但其含义略有不同。
例如,在.NET中,当您使用本机类型时,交互层会将数据从.NET类型“marshals”到适当的形式以调用本机方法,然后再“marshals”结果回来。
至于在线程之间“marshalling”,通常情况下,您需要在与当前线程不同的线程上运行代码。例如,如果您正在使用Windows Forms,您无法在线程池线程上更改UI元素,因此您需要将调用“marshal”回UI线程。通过创建委托并通过Control.Invoke将委托传回用户界面线程(该方法使用相当复杂的系统将其发送回适当的同步上下文),然后在用户界面线程上运行委托。
维基百科 的定义其实相当不错。
对于内存序列化的概念,它与 marshalling 的概念是一致的:将从内存中表示(在某种程度上,就像没有任何表示一样——当某些东西在内存中时,它只是“存在”)转移到“硬拷贝”表示,无论是 XML 或者二进制流等。但是,根据您正在处理的内容,它也可能意味着要将其转换或翻译到目标格式。
对于进程间通信的 marshalling:一个线程不能简单地“调用”另一个线程——数据必须被打包并“发送”到另一个线程。Marshalling 是打包数据的过程(例如,关于要调用的方法及其参数的数据)。
如果您在进行互操作方面的 marshalling,则需要将方法调用及其参数打包成可以发送到运行 COM 组件的进程/线程的数据结构。该包需要以 COM 组件能够理解的格式进行。
编组(类似于序列化)是将对象的内存表示转换为适合于存储或传输的数据格式的过程。通常在需要在计算机程序的不同部分之间或从一个程序到另一个程序移动数据时使用。
当从.NET调用未托管的函数时,编组用于将.NET的数据转换成未托管函数可以使用的数据。例如,System.String
是基于Unicode的,但该字符串可能需要转换为ANSI字符串以便传递给未托管的C函数。
对于线程,编组通常指将某些数据的所有权从一个线程转移到另一个线程。例如,程序有两个线程。第一个线程从网络中读取数据,第二个线程计算该数据。在网络线程读取一些数据后,它会将数据转移(即“编组”)到计算线程进行处理。它可能通过将数据写入两个线程之间共享的队列来实现。
在线程中的编组几乎总是涉及到正在编组的数据的同步。
通常用于“以XML格式编写”的上下文中,但它可以转换为任何格式。
2. To arrange, place, or set in methodical order.
(from American Heritage® Dictionary of the English Language)
这意味着您正在按照所需的系统化顺序/格式排列数据。通常情况下,这是以XML格式进行的。