Próbuję uzyskać moją głowę wokół async/czekać i myślałem, że rozumiem kilka rzeczy na temat użytkowania. Ale wciąż nie całkiem jasne, jaka byłaby faktyczna korzyść w scenariuszu, jak poniżej.Co to za różnica - uruchamianie delegata akcji "async" z Task.Run (kontra domyślny delegat akcji)?
Spójrz na użycie Task.Run. Pierwsza metoda używa normalnego delegata i używa Thread.Sleep, ale druga używa "async" delegata i Task.Delay.
Moje pytanie brzmi: jak to ma wpływ na tę metodę (lub nie)?
Sama metoda jest metodą asynchroniczną. Kod tworzy osobny wątek (za pośrednictwem Task.Run), a ten wątek nie ma nic innego do roboty poza wykonywaniem tego delegata. Tak więc, nawet jeśli przynosi oczekiwanie na Task.Delay, jaki jest pożytek z tego scenariusza, ponieważ wątek jest w każdym razie izolowanym wątkiem, który nie jest używany do niczego innego, a nawet jeśli używa tylko Thread.Sleep, wątek nadal byłby kontekstem przełącz się na inne wątki procesora.
// The task thread uses a async delegate
public async Task<bool> RetrySendEmail(MailMessage message)
{
bool emailSent = false;
await (Task.Run(***async()*** =>
{
for (int i = 0; i < 3; i++)
{
if (emailSent)
break;
else
// Wait for 5 secs before trying again
***await Task.Delay(5000);***
try
{
Smtphost.Send(message);
emailSent = true;
break;
}
catch (Exception e) { emailSent = false; // log; }
}
return emailSent;
}));
}
// The task thread uses a normal delegate
public async Task<bool> RetrySendEmail(MailMessage message)
{
bool emailSent = false;
await (Task.Run(***()*** =>
{
for (int i = 0; i < 3; i++)
{
if (emailSent)
break;
else
// Wait for 5 secs before trying again
***Thread.Sleep(5000);***
try
{
Smtphost.Send(message);
emailSent = true;
break;
}
catch (Exception e){ emailSent = false; // log; }
}
return emailSent;
}));
}
Dziękuję, to jest pomocne. Trochę poza ścieżką asynchroniczną, ale w tym przykładzie utworzyłem nowy wątek (z Task.Run, ponieważ "Smtphost.Send" to blokujące wywołanie IO), więc pomyślałem, że ma sens przeniesienie tego do osobnego wątku. myślisz, że to nie ma znaczenia? –
@EverythingMatters 'Task.Run' nie tworzy wątku, używa wątku' ThreadPool'. Możesz to zrobić, jeśli chcesz odciążyć pracę do innego wątku (jest to użyteczne na przykład, aby odblokować wątek GUI), ale to nie poprawia wydajności .Jeśli oryginalny wątek jest wątkiem "ThreadPool", blokowanie innego nie dodaje żadnej wartości. – i3arnon