it-swarm.com.de

wie berechnet man die Ausführungszeit einer asynchronen Methode in c #

Ich habe also eine Async-Methode, die etwas asynchron macht.

private async static void DoSomethingAsync (int i){}

Ich nenne es in einer Schleife sagen wir 50 mal.

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

Am Ende der Schleife möchte ich die Gesamtverarbeitungszeit berechnen, ich habe Stoppuhr verwendet, aber wie Sie sich vorstellen können, gibt sie mir die falsche Zeit, wenn sie aufgerufen wird, sobald die Schleife beendet ist. Sie wartet nicht, bis DoSomethingAsync die Verarbeitung beendet hat.

so weisen Sie Stopwatch an, auf die Beendigung aller 50 Instanzen von DoSomethingAsync () zu warten. Ich habe diese Frage gesehen, aber ich kann Task hier nicht verwenden.

5
ahsant

Ich weiß nicht, warum Sie Task nicht verwenden können. Ich vermute, dass Sie es in einer Main-Methode oder so aufrufen. Also werde ich davon ausgehen.

Wie Martin Ullrich sagte, ich würde DoSomethingAsync Methode ändern, um eine Aufgabe zurückzugeben:

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

Erstellen Sie dann eine neue Methode, die die Schleife durch Hinzufügen der Methoden zu einem List<Task> ausführt:

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);
}

In diesem Fall fügt die Methode Main einfach den neuen Methodenaufruf hinzu:

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

    Console.ReadLine();
}
4
Mike

Dies ist der Nachteil der Verwendung von async void. Es gibt keine Möglichkeit, dies zu tun, ohne die aufgerufene Methode zu ändern (so dass sie einen Rückruf aufrufen, einen Mutex entsperren usw.).

Sie können Ihre Methode so ändern, dass stattdessen async Task zurückgegeben wird, und eine andere Methode erstellen, die diese Methode nur ohne Wartezeit aufruft und dann an Stellen verwendet werden kann, für die Sie zuvor die async void-Signatur benötigt haben.

4
Martin Ullrich

async void warum? Tun Sie das nicht, verwenden Sie asnyc Task oder eine ActionBlocks oder einen ParallelFor/ForEach. Wenn Sie die Zeit in einem parallelen Prozess berechnen möchten, sollten Sie einen Zeitgeber in Ihre parallele Methode einfügen und eine globale Variable verwenden. Verwenden Sie dazu Interlocked.Add Method . Methode zur Gewindesicherheit

private long CombinedMs;

...

private async static void DoSomethingAsync (int i)
{

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

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

}

Wie auch immer, ich denke, Sie müssen bei den Aufgaben wieder zum Zeichenbrett zurückkehren ... Viel Glück

2
Michael Randall

Sie können einen globalen Zähler verwenden, um den Zeitaufwand zu erfassen.

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