web-dev-qa-db-ja.com

C#で非同期メソッドの実行時間を計算する方法

だから私は非同期で何かをするAsyncメソッドを持っています。

private async static void DoSomethingAsync (int i){}

私はそれをループで50回言います。

for (int i = 0; i < 50; i++)
 {
    DoSomethingAsync (i);
 }

ループの終わりに合計処理時間を計算したいので、ストップウォッチを使用しましたが、ループの直後に呼び出されると間違った時間が表示されるので、DoSomethingAsyncが処理を終了するのを待ちません。

doSomethingAsync()の50個のインスタンスすべてが終了するのを待つようにStopwatchに指示する方法。 this の質問を見ましたが、ここではタスクを使用できません。

6
ahsant

Taskを使用できない理由はわかりませんが、Mainメソッドなどで呼び出していると思います。だから私はそこから出かけます。

Martin Ullrichが言ったように、タスクを返すためにDoSomethingAsyncメソッドを変更します。

private async static Task DoSomethingAsync(int i)
{
    ...
}

次に、メソッドをList<Task>に追加して、ループを実行する新しいメソッドを作成します。

private static async void PerformLoop()
{
    Stopwatch timer = new Stopwatch();
    timer.Start();
    List<Task> l = new List<Task>();
    for (int i = 0; i < 50; i++)
    {
        l.Add(DoSomethingAsync(i));
    }
    await Task.WhenAll(l);
    timer.Stop();

    Console.WriteLine(timer.Elapsed.TotalSeconds);
}

以前にループを実行した場所から、この場合はMainメソッドが新しいメソッド呼び出しをそこに追加するだけです。

static void Main(string[] args)
{
    PerformLoop();

    Console.ReadLine();
}
7
Mike

これは、async voidを使用することの欠点です。呼び出されたメソッドを変更せずにこれを行う方法はありません(コールバックを呼び出したり、ミューテックスのロックを解除したりできるようにするため)。

代わりにasync Taskを返すようにメソッドを変更し、待機せずにこのメソッドを呼び出すだけの別のメソッドを作成して、以前にasync void署名が必要だった場所で使用できます。

4
Martin Ullrich

async voidなぜですか?そうしないでください。asnyc Task、またはActionBlocksまたはParallelFor/ForEachを使用してください。ただし、純粋に目新しさのために(そして真のゲージとして使用されないように)、並列プロセスIDで時間を計算する場合は、並列メソッド内にタイマーを配置し、グローバル変数を使用して Interlocked.Addメソッドを使用することを検討してください) スレッドセーフの方法

private long CombinedMs;

...

private async static void DoSomethingAsync (int i)
{

   var sw = new StopWatch();
   sw.Start();
   ...
   sw.Stop();

   Interlocked.Add(ref CombinedMs,sw.ElapsedMillisecond);

}

とにかく、私はあなたが仕事で画板に戻る必要があると思います...頑張ってください

3
AAAbbbCCCddd

このような、消費された時間を追跡するためのグローバルカウンターを持つことができます。

public class YourClass
{

TimeSpan tSpan;


public void PerformOp()
{
tSpan=new TimeSpan();
for (int i = 0; i < 50; i++)
 {
    DoSomethingAsync (i);
 }

}

private async static void DoSomethingAsync (int i)
{
Stopwatch stp = new StopWatch();
stp.Start();
//your Operation here
stp.Stop();
tSpan+=stp.Elapsed;//not the exact systax or usage but you get the idea 
}

}
0
Dharani Kumar