2017-06-15 13 views
1
private class ParamDatas 
{ 
    public object Param1; 
    public object Param2; 
} 

private static void Main(string[] args) 
{ 
    Action<ParamDatas> action = ThreadAction; 
    var myParamDatas = new ParamDatas(); 
    var result = action.BeginInvoke(myParamDatas, null, null); 

    // dosomething ... 
} 

private static void ThreadAction(ParamDatas paramDatas) 
{ 
    Thread.MemoryBarrier(); 

    // use paramDatas .... 
    // var param1 = paramDatas.Param1; 
} 

このコードでは、MemoryBarrierは必要ですか? またはBeginInvoke関数によってデータがダーティーにならない?Delegate.BeginInvokeにはMemoryBarrierが必要ですか?

答えて

-1

はい、MemoryBarrierの使用が必要です(またはモニター/ロック)。同期メカニズムを使用して独自のスレッドセーフティ保証を提供する必要があります。

デリゲートの呼び出しは、スレッドセーフです。デリゲートを参照するメソッドの実行はスレッドセーフではないため、スレッドセーフです。

は、スレッドの安全性に関する記事MulticastDelegate Classから直接引用:「すべてのパブリックstatic(Visual BasicではShared)このタイプのメンバーは、スレッドセーフでインスタンスメンバーの場合は、スレッドセーフであるとは限りません

I

+0

私はダウン投票のためのいくつかのフィードバックがありますか –

0

BeginInvokeに電話をかけた時点で、myParamDatasのコピーを取得し、そのデータのコピーを関数呼び出しに送信しています。その値にはメモリバリアや同期メカニズムは必要ありません。同様に、変数に対する任意の突然変異またはその値値が読み込まれる前にその関数呼び出しを実行する必要がある前に、その時点での値の読み取りはそれらの変更と同じスレッド上にあるため、順序どおりに実行する必要があります。これは、BeginInvokeを呼び出す前にそのオブジェクトに値を設定した場合、それらの値が呼び出された関数で観測可能であることを意味します。

あなたは(呼び出し元のスレッド上で)BeginInvokeを呼び出し後に参照されたオブジェクトに変更を作っているなら、あなたはそれらの変更が正しくからのオブジェクトの使用方法と同期されることを保証するために、適切な同期化機構が必要になりますがもう一方のスレッド。

関連する問題