2016-01-08 8 views
6

ExecutionContext.Capture()ExecutionContext.Run(context, work, state)には高価な人がいますか?ExecutionContext.Capture()とExecutionContext.Runのコスト(コンテキスト、作業、状態)

パフォーマンスが低下するため、注意深く使用することをお勧めしますか?

私はContextItemを持っているので、後で実行するためにContextの作業と状態を保存しています。私は仕事を実行している間にスローされるかもしれない例外に反応できるようにしたいので、例外がスローされた場合に実行されるフォールバックを持っています。また、例外がスローされたかどうかにかかわらず、どのような場合でも実行される最終的な作業があります。 私はExecutionContextを一度しか使用できないので、これらのContextItemsの1つに対してExecutionContext.Capture()を3回実行する必要があります。

これはまったく間違ったアプローチですか? @Aloisクラウスによって推奨されているように

+3

コメントなしのダウンボートは役に立ちません。 – fosb

+3

@cory nelsonロックで問題を解決できるのであれば、それはチュートリアルですか? 正直なところ、質問がうまくいかないと言うのは公正ではないと思います.ExpressutoでのExecutiocontextの質問のどれも、使用するのに費用がかかっているかどうか、またこのトピックで見つかったオンラインのページはありません。だから私は何かを知らない、あるいは私が質問をしてはならない説明を理解していないと言う?その後、このウェブサイトの感覚はどこですか? – fosb

+1

投稿したコードはすべてあなたが必要とするものです。 1000万回の反復でforループを置き、あなた自身でチェックアウトしてください。あなたがそれを頻繁に呼び出すかどうかは、コストが問題になるかどうかによって決まります。 –

答えて

1

私は、次のコードは、&並んexcecutionをキャプチャするロックと比較してテストを実行しました:

class Program 
{ 
    private static readonly object _lock = new object(); 
    private static readonly int numberOfItems = 1000000; 
    private static readonly int _numberOfIterations = 1000000; 

    private static void Main(string[] args) 
    { 
     MeasureTimeWithLocking(); 
     MeasureTimeWithCapuringContext(); 
     Console.WriteLine(); 
     MeasureTimeWithLocking(); 
     MeasureTimeWithCapuringContext(); 
     Console.WriteLine(); 
     MeasureTimeWithLocking(); 
     MeasureTimeWithCapuringContext(); 
     Console.ReadKey(); 
    } 

    private static void MeasureTimeWithLocking() 
    { 
     List<ContextItem> items = new List<ContextItem>(); 
     Stopwatch stopwatch = Stopwatch.StartNew(); 
     for (int i = 0; i < numberOfItems; i++) 
     { 
      ContextItem item = new ContextItem(); 
      item.Work1 = DoSomeWorkWithLock; 
      item.Work2 = DoSomeWorkWithLock; 
      item.Work3 = DoSomeWorkWithLock; 
     } 

     Parallel.ForEach(items, (item) => 
     { 
      item.Work1(null); 
      item.Work2(null); 
      item.Work3(null); 
     }); 
     stopwatch.Stop(); 
     Console.WriteLine("Time elapsed with locking:   " + stopwatch.Elapsed); 
    } 

    private static void MeasureTimeWithCapuringContext() 
    { 
     List<ContextItem> items = new List<ContextItem>(); 
     Stopwatch stopwatch = Stopwatch.StartNew(); 
     for (int i = 0; i < numberOfItems; i++) 
     { 
      ContextItem item = new ContextItem(); 
      item.Context1 = ExecutionContext.Capture(); 
      item.Context2 = ExecutionContext.Capture(); 
      item.Context3 = ExecutionContext.Capture(); 
      item.Work1 = DoSomeWork; 
      item.Work2 = DoSomeWork; 
      item.Work3 = DoSomeWork; 
     } 

     foreach (ContextItem item in items) 
     { 
      ExecutionContext.Run(item.Context1, item.Work1, null); 
      ExecutionContext.Run(item.Context2, item.Work2, null); 
      ExecutionContext.Run(item.Context3, item.Work3, null); 
     } 
     stopwatch.Stop(); 
     Console.WriteLine("Time elapsed with capturing context: " + stopwatch.Elapsed); 
    } 

    private static void DoSomeWork(object ignored) 
    { 
     Work(); 
    } 


    private static void DoSomeWorkWithLock(object ignored) 
    { 
     lock (_lock) 
     { 
      Work(); 
     } 
    } 

    private static void Work() 
    { 
     int count = 0; 
     for (int i = 0; i < _numberOfIterations; i++) 
     { 
      count ++; 
     } 
    } 

    private class ContextItem 
    { 
     public ExecutionContext Context1 { get; set; } 
     public ExecutionContext Context2 { get; set; } 
     public ExecutionContext Context3 { get; set; } 

     public ContextCallback Work1 { get; set; } 
     public ContextCallback Work2 { get; set; } 
     public ContextCallback Work3 { get; set; } 
    } 
} 

結果は以下のとおりです。

enter image description here

だから私がやった場合この権利は、&を実行して実行すると、ロックより約5倍高価です。

また、私の質問の一部に答えるために:

または完全に間違ったアプローチのように、この音をするの?

私は、あなたは彼らがそこにいる知っている必要があれば

、あなたは超高度な何かをやっている、または何かが間違っていますいずれかのことをthis articleで読み取ります。

この記事は、ExecutionContextについて知りたい場合は、SOのベストソースとして推奨されています。 これを実行して同僚といくつかのテストを実行した後、私はExecutionContextを使用していることに気付きました。さらに、ロックよりパフォーマンスが悪く、他のスレッド機能/構造よりパフォーマンスが劣る可能性があります。

関連する問題