Chcę wykonać 10 asynchronicznych żądań http na raz i przetwarzać wyniki tylko wtedy, gdy wszystkie zostały zakończone i w jednej funkcji wywołania zwrotnego. Nie chcę również blokować żadnych wątków za pomocą WaitAll (rozumiem, że WaitAll blokuje dopóki wszystkie nie zostaną zakończone). Myślę, że chcę utworzyć niestandardową funkcję IAsyncResult, która będzie obsługiwać wiele połączeń. Czy jestem na dobrej drodze? Czy istnieją jakieś dobre zasoby lub przykłady, które opisują obsługę tego?C# wiele asynchronicznych HttpRequest z jednym oddzwanianiem
Odpowiedz
Podoba mi się rozwiązanie Darina. Ale jeśli chcesz czegoś bardziej tradycyjnego, możesz spróbować tego.
Zdecydowanie używać tablicy uchwytów poczekać i mechanizm WaitAll:
static void Main(string[] args)
{
WaitCallback del = state =>
{
ManualResetEvent[] resetEvents = new ManualResetEvent[10];
WebClient[] clients = new WebClient[10];
Console.WriteLine("Starting requests");
for (int index = 0; index < 10; index++)
{
resetEvents[index] = new ManualResetEvent(false);
clients[index] = new WebClient();
clients[index].OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
clients[index].OpenReadAsync(new Uri(@"http:\\www.google.com"), resetEvents[index]);
}
bool succeeded = ManualResetEvent.WaitAll(resetEvents, 10000);
Complete(succeeded);
for (int index = 0; index < 10; index++)
{
resetEvents[index].Dispose();
clients[index].Dispose();
}
};
ThreadPool.QueueUserWorkItem(del);
Console.WriteLine("Waiting...");
Console.ReadKey();
}
static void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
// Do something with data...Then close the stream
e.Result.Close();
ManualResetEvent readCompletedEvent = (ManualResetEvent)e.UserState;
readCompletedEvent.Set();
Console.WriteLine("Received callback");
}
static void Complete(bool succeeded)
{
if (succeeded)
{
Console.WriteLine("Yeah!");
}
else
{
Console.WriteLine("Boohoo!");
}
}
Spójrz na ten artykuł Asynchronous Calls in .NET - Polling or Waiting for Completion
myślę, że jesteś lepiej wyłączyć za pomocą podejścia WaitAll. W przeciwnym razie przetwarzasz 10 wywołań zwrotnych IAsyncResult i używasz semafora do określenia, że wszystkie 10 są w końcu ukończone.
Należy pamiętać, że funkcja WaitAll jest bardzo wydajna; to nie jest jak głupota posiadania wątku "spać". Gdy wątek śpi, nadal używa czasu przetwarzania. Kiedy wątek jest "nieplanowany", ponieważ trafił na WaitAll, wątek nie zużywa już czasu procesora. Jest bardzo wydajny.
W kontekście puli wątków IIS, wątek jest nadal w użyciu lub zostałby przywrócony do puli, tak jak w przypadku wywołania asynchronicznego? – aepheus
W .NET 4.0 jest ładny równolegle Task library że pozwala robić takie rzeczy jak:
using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
class Program
{
public static void Main()
{
var urls = new[] { "http://www.google.com", "http://www.yahoo.com" };
Task.Factory.ContinueWhenAll(
urls.Select(url => Task.Factory.StartNew(u =>
{
using (var client = new WebClient())
{
return client.DownloadString((string)u);
}
}, url)).ToArray(),
tasks =>
{
var results = tasks.Select(t => t.Result);
foreach (var html in results)
{
Console.WriteLine(html);
}
});
Console.ReadLine();
}
}
Jak widać dla każdego adresu URL z listy inny zadaniem jest uruchamiany i gdy wszystkie zadania są uzupełnione wywołanie zwrotne jest wywoływane i przekazuje wynik wszystkich zadań.
W rzeczywistości wywoła ona synchroniczne wywołanie w osobnym wątku roboczym. Aby rozwiązać ten problem, powinieneś użyć 'TaskFactory.FromAsync' +' client.BeginGetResponse'. W ten sposób zostaną użyte porty ukończenia operacji we/wy bez blokowania wątków. – VirusX
- 1. Wiele suwaków z jednym oddzwanianiem
- 2. Zmienna liczba asynchronicznych wątków z C++ 11
- 3. Wiele konstruktorów z jednym parametrem
- 4. Wiele kontrolerów z jednym modelem
- 5. Wyślij wiele asynchronicznych żądań na klienta Netty
- 6. Android: jak wyświetlić podgląd kamery z oddzwanianiem?
- 7. Wiele parametrów w jednym parametrze (funkcje) w C/C++
- 8. Oczekiwanie na wiele asynchronicznych żądań POST
- 9. Zaplanuj wiele zadań asynchronicznych w systemie Android
- 10. Oczekiwanie na wiele asynchronicznych zadań pobierania
- 11. Node.js - czekaj na wiele asynchronicznych wywołań
- 12. EF Wiele baz danych z jednym kontekstem
- 13. Co jest lepsze dla wydajności - wiele plików w jednym katalogu lub wiele podkatalogów z jednym plikiem?
- 14. Wiele UICollectionView w jednym kontrolerze
- 15. Wiele repozytoriów w jednym katalogu
- 16. Wiele PickerViews w jednym widoku?
- 17. Jaka jest różnica między połączeniami asynchronicznymi a oddzwanianiem
- 18. C# wiele argumentów w jednym do DRY out przepuszczanie parametrów
- 19. Wiele UITableViews na jednym UIView
- 20. Wiele kodów prób w jednym bloku
- 21. Wiele SELECT w jednym zapytaniu
- 22. Wiele kolumn w jednym StaggeredGridView?
- 23. Jak uruchomić wiele poleceń w jednym wierszu?
- 24. Wiele klas w jednym pliku .cpp
- 25. Javascript - jak pracować z iteratorem w pętli for z oddzwanianiem
- 26. Konwertuj HttpRequestMessage na HttpRequest
- 27. NSURLConnection i wiele asynchronicznych żądań - czy zakłóca przesyłane dane?
- 28. Porządek wyszukiwania indeksera HttpRequest
- 29. Wiele wierszy z jednym INSERT w SQLServer 2008
- 30. Isomorphic JS - tylko strona z klientem httpRequest
Jaki jest kontekst tej operacji? Wewnątrz strony internetowej? – Keltex
Tego typu rzeczy są bardzo banalne w języku F #. Warto napisać moduł w języku F #, który można wywołać z kodu C# ... –
@Keltex byłby częścią aplikacji internetowej. – aepheus