2011-07-06 11 views
5

バックグラウンドワーカーとの間でやり取りされるデータはどうなりますか?バックグラウンドワーカーとの間でやり取りされるデータはどうなりますか?

データはRunWorkerAsyncを使用してバックグラウンドワーカーにメインスレッドから渡されます。これは、バックグラウンドスレッドでDoWorkイベントハンドラで受信された

backgroundWorker.RunWorkerAsync(myData); 

myData = (Data)e.Argument; 

DoWorkが処理した後データ、eを使用して返します。結果:

e.Result = myData; 

これはメインスレッドのRunWorkerCompletedイベントハンドラ:

myData = (Data)e.Result; 

BackgroundWorkerはスレッド間でデータを受け渡ししています。大量のデータをバックグラウンドワーカーとの間でやりとりすることを期待しているので、この転送のオーバーヘッドを知りたいし、バックグラウンドワーカーで大量のメモリ内オブジェクトを処理するより良い方法があるかどうかを知りたい。スレッドセーフな方法でバックグラウンドワーカーのデータにメインスレッドからアクセスすることが可能であることを知りたいと思います。

参考までに、私はC#、.Net 3.5、Windows Formsを使用しています。

答えて

6

参照のみが渡されるので、実際にオーバーヘッドはありません(Dataがクラスです)。データそのものはスレッドに「コピー」されません。すべてのスレッドがプロセス内のデータにアクセスできます(ほとんどの場合)。

スレッドセーフな方法でバックグラウンドワーカーのデータにメインスレッドからアクセスすることもできます。

はい、データにアクセスすることは可能ですが、スレッドセーフな方法で行うには、同期を自分で管理する必要があります。これには通常、lockのようなものが必要ですが、達成しようとしていることに応じて多くのオプションがあります。

+0

+1質問のマルチスレッド同期部分に答えるための+1。 –

5

オブジェクトは、です。常にが渡されます。どんなオーバーヘッドもありません。

BackgroundWorkerは、オブジェクトを内部キューに追加してから、UIスレッドのキューからオブジェクトを読み取ります。 (これは実際にControl.MarshaledInvokeによって行われます)

+0

+1 - データがクラスの場合にのみ* always *が真であることを除けば... –

+0

@Reed:彼はObject型で、値型のボクシングを意味します。しかし、答えの文言はあいまいです。 –

1

転送には基本的にオーバーヘッドはありません。それは単なるオブジェクト参照です(関連するデータのマーシャリングは一切ありません)。 RunWorkerAsyncとRunWorkerCompletedの呼び出しの間にメインスレッドがデータにアクセスしない限り、スレッドセーフです。

関連する問題