Po przeczytaniu this post kilka miesięcy temu, stałem się paranoikiem na uzyskanie Result
z Task<T>
i nieustannie pakowałem wszystkie moje połączenia do niego za pomocą ConfigureAwait(false)
lub Task.Run
. Jednak z jakiegoś powodu poniższy kod zakończy się pomyślnie:Dlaczego nie wywoływanie zadania <T>.
public static void Main(string[] args)
{
var arrays = DownloadMany();
foreach (var array in arrays);
}
IEnumerable<byte[]> DownloadMany()
{
string[] links = { "http://google.com", "http://microsoft.com", "http://apple.com" };
using (var client = new HttpClient())
{
foreach (var uri in links)
{
Debug.WriteLine("Still here!");
yield return client.GetByteArrayAsync(uri).Result; // Why doesn't this deadlock?
}
}
}
drukuje kod Still here!
3 razy, a następnie kończy działanie. Czy to jest specyficzne dla HttpClient
, że można bezpiecznie zadzwonić pod numer Result
(jak u ludzi, którzy go napisali, zasypali go ConfigureAwait(false)
)?
przy okazji ... znacznie łatwiej jest nie blokować i używać w razie potrzeby czekania, niż wszędzie gdzie jest "ConfigureAwait". – i3arnon
@ i3arnon To prawda, ale piszę interfejs API obsługujący zarówno synchroniczne, jak i asynchroniczne wywoływania. –
@JamesKo: Zalecam, aby metody asynchroniczne udostępniały asynchroniczne interfejsy API. Jeśli jednak * musisz * obsługiwać zarówno synchronizację, jak i asynchronię (np. W celu zapewnienia kompatybilności wstecznej), możesz znaleźć mój ostatni [artykuł MSDN na temat asynchronicznego kontekstu brownfield] (https://msdn.microsoft.com/en-us/magazine/ mt238404.aspx) przydatne. –