2017-02-12 4 views
3

これらの2つのサンプルは同じですか?古いスタイルのレイジングをInvokeとnull propagationに置き換えることはできますか?ヌル伝播によるイベント発生のスレッドセーフ

OLD:

public event EventHandler<MyEventArgs> MyEvent; 
    protected virtual void OnMyEvent(MyEventArgs args) 
    { 
     EventHandler<MyEventArgs> handler = this.MyEvent; 
     if (handler != null) 
      handler(this, args); 
    } 

NEW:

public event EventHandler<MyEventArgs> MyEvent; 
    protected virtual void OnMyEvent(MyEventArgs args) 
    { 
     this.MyEvent?.Invoke(this, args); 
    } 

ヌルチェックは重要ですが、それは明らかです。追加の変数は何ですか?
ヌルプロパゲーションは内部的にどのように機能しますか?イベントではスレッドセーフですか?

P.S.イベントでは、スレッドの安全性について、あなたはここで読むことができます。
C# Events and Thread Safety

+0

関連:https://codeblog.jonskeet.uk/2015/01/30/clean-event-handlers-invocation-with-c-6/ – VMAtm

+0

また、ロシア語のリンク:https://habrahabr.ru/ post/89529 /とhttps://habrahabr.ru/post/240385/ – VMAtm

+0

これは重複していません..少なくともスレッドセーフティはこの質問の特定のトピックです..以前の投稿の回答では何か不思議なことを言っています。 PropertyChangedを一度だけ評価し、結果を一時変数に保持する "..スレッドセーフについては何もしません。コピーの事実だけが問題です!それが@eocronによって調査されました。だから違いがあります。正確に何が起こったのかを理解するには、以前の記事よりもこの投稿から回答を得る方がはるかに良いです。 – Maxim

答えて

6

は、このコードを考える:これは私が単項演算子は(2015 VS)リリースモードで呼び出されたラインでIL表現で見るものである

static void Main(string[] args) 
    { 
     var a = new Random(1).Next() > 0 ? new object() : null; 
     var b = a?.GetHashCode(); 
     Console.WriteLine(b); 
    } 

IL_0016: dup   
IL_0017: brtrue.s  IL_0025 

... //nothing iteresting, just setting null to 'a' and skip IL_0025 area 

IL_0025: callvirt  instance int32 [mscorlib]System.Object::GetHashCode() 

は私に説明してみましょう:

  • DUPは、 - 転送がオン値場合に対処するために、制御 - このスタックに配置され、新しいものにそのスタック上のコピー電流値をコマンド(この場合には、単に「A」の値を複製された)
  • brtrue.sありますYES、それはスレッドである:だから、

あなたの質問への答えは - スタックは、(スレッドセーフにそれを使用することで、今のよう値が「A」のコピーである)真/にnotnull /非ゼロであります-adafeはモナド演算子を使用するために、コピー上で動作しているためです。

+0

ILの仕事に感謝します!今はかなり明確です...それはコピーになります。 – Maxim

+0

このバージョンは壊れませんが、理論上はまだスレッドセーフなソリューションではありません。実際には、それはOKレベルのソリューションです – VMAtm

+0

イベント自体の発生はスレッドセーフです...他のコードのスレッドの安全性は関係ありません。 – Maxim

関連する問題