传入和传出后台工作人员的数据会发生什么情况?
传入和传出后台工作人员的数据会发生什么情况?
使用 RunWorkerAsync 将数据从主线程传递到后台工作程序:
backgroundWorker.RunWorkerAsync(myData);
这是在后台线程中的 DoWork 事件处理程序中接收的:
myData = (Data)e.Argument;
DoWork 处理完数据后,它使用 e.Result 返回它:
e.Result = myData;
这是在 RunWorkerCompleted 事件处理程序中接收的在主线程中:
myData = (Data)e.Result;
BackgroundWorker 负责在线程之间传递数据。我期望向后台工作人员传递大量数据或从后台工作人员传递大量数据,因此我想知道此传输的开销是多少,以及是否有更好的方法来处理后台工作人员中的大量内存中对象。我还想知道是否可以以线程安全的方式从主线程访问后台工作人员中的数据。
作为参考,我使用 C#、.Net 3.5 和 Windows 窗体。
What happens to the data that is passed to and from a background worker?
Data is passed from the main thread to the background worker using RunWorkerAsync:
backgroundWorker.RunWorkerAsync(myData);
This is received in the DoWork event handler in the background thread:
myData = (Data)e.Argument;
After DoWork has processed the data, it returns it using e.Result:
e.Result = myData;
This is received in the RunWorkerCompleted event handler in the main thread:
myData = (Data)e.Result;
BackgroundWorker is taking care of passing the data between the threads. I am expecting to pass large amounts of data to and from a background worker so I want to know what the overhead of this transfer is, and if there is a better way of processing a large amount of in-memory objects in a background worker. I would also like to know it is possible to access the data in the background worker from the main thread in a thread-safe manner.
For reference, I am using C#, .Net 3.5 and Windows Forms.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实际上没有任何开销(假设 Data 是一个类),因为只传递引用。数据本身不会“复制”到线程中 - 所有线程都可以访问进程中的数据(大多数情况下)。
是的,可以访问数据,但为了以线程安全的方式进行访问,您需要自己管理同步。这通常需要诸如
锁
之类的东西,尽管有很多选项取决于您想要完成的任务。There really is no overhead (provided
Data
is a class), since only the reference is passed around. The data itself isn't "copied" into a thread - all threads can access the data in the process (for the most part).Yes, it's possible to access the data, but in order to do it in a thread-safe manner, you'll need to manage the synchronization yourself. This typically requires something like a
lock
, though there are many options depending on what you are trying to accomplish.对象总是通过引用传递。没有任何开销。
BackgroundWorker
只是将对象添加到内部队列,然后在 UI 线程上从队列中读取它。 (这实际上是由Control.MarshaledInvoke
完成的)Objects are always passed by reference. There is no overhead whatsoever.
BackgroundWorker
simply adds the object to an internal queue, then reads it off the queue on the UI thread. (This is actually done byControl.MarshaledInvoke
)传输过程中基本上没有任何开销;它只是一个对象引用(没有对所涉及的数据进行编组)。只要主线程在调用 RunWorkerAsync 和 RunWorkerCompleted 之间不访问数据,您就是线程安全的。
There is essentially no overhead in the transfer; it is just an object reference (there's no sort of marshaling of the data involved). You are thread safe as long as the main thread does not access the data between the call to RunWorkerAsync and RunWorkerCompleted.