Я хочу сделать 10 асинхронных HTTP-запросов сразу и обрабатывать результаты только после завершения и в одной функции обратного вызова. Я также не хочу блокировать любые потоки, используя WaitAll (я понимаю, что WaitAll блокирует, пока все не будет завершено). Я думаю, что хочу создать пользовательский IAsyncResult, который будет обрабатывать несколько вызовов. Я на правильном пути? Есть ли хорошие ресурсы или примеры, которые описывают обработку этого?C# несколько асинхронных HttpRequest с одним обратным вызовом
ответ
Мне нравится решение Дарина. Но, если вы хотите что-то более традиционное, вы можете попробовать это.
Я бы определенно использовать массив ожидания ручек и механизм 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!");
}
}
Посмотрите на эту статью Asynchronous Calls in .NET - Polling or Waiting for Completion
Я думаю, что вы лучше использовать подход WaitAll. В противном случае вы будете обрабатывать 10 обратных вызовов IAsyncResult и использовать семафор, чтобы определить, что все 10 завершены.
Имейте в виду, что WaitAll очень эффективен; это не похоже на глупость иметь «сон». Когда поток спит, он продолжает использовать время обработки. Когда поток «отменен», поскольку он попадает в WaitAll, поток больше не потребляет процессорное время. Это очень эффективно.
В контексте пула потоков IIS этот поток по-прежнему используется или он будет возвращен в пул, как и для асинхронного вызова? – aepheus
В .NET 4.0 есть хороший параллельный Task library, что позволяет делать такие вещи, как:
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();
}
}
Как вы можете видеть, для каждого URL в списке запускается другая задача, и как только все задачи завершено обратный вызов вызывается и передается результат всех задач.
На самом деле, он просто сделает синхронный вызов в отдельном рабочем потоке. Чтобы решить эту проблему, вы должны использовать 'TaskFactory.FromAsync' +' client.BeginGetResponse'. Таким образом, порты завершения ввода-вывода будут использоваться без блокировки потока. – VirusX
- 1. Несколько запросов Ajax (с одним обратным вызовом)
- 2. Сделать несколько асинхронных HTTP-запросов с одним обратным вызовом на C#
- 3. Выполнение асинхронных функций с обратным вызовом?
- 4. Несколько одновременных запросов Ajax (с одним обратным вызовом) в jQuery
- 5. Несколько зацикленных запросов ajax с одним обратным вызовом
- 6. Несколько вызовов ajax с одним отказоустойчивым обратным вызовом
- 7. javascript: выполнить кучу асинхронного метода с одним обратным вызовом
- 8. C++ измеряет время между вызовом функции и обратным вызовом
- 9. Создание асинхронных методов с фабрикой задач и обратным вызовом
- 10. jquery plugin несколько экземпляров с обратным вызовом
- 11. Разница между обратным вызовом и обратным вызовом
- 12. document.createElement ('script') ... добавление двух скриптов с одним обратным вызовом
- 13. Проблема с обратным вызовом Objective-C iOS
- 14. preg_match_all с обратным вызовом?
- 15. Функция с обратным вызовом
- 16. Таймер с обратным вызовом
- 17. Инициализировать вектор с обратным вызовом
- 18. Связи SWIG C++ с обратным вызовом
- 19. Async будущее с обратным вызовом. C++ 11
- 20. Проблемы с обратным вызовом Nodejs
- 21. Проблемы с обратным вызовом JNA
- 22. Вызов MiniDumpWriteDump с обратным вызовом
- 23. Node.js Проблемы с обратным вызовом
- 24. ARC, между блоком и обратным вызовом C
- 25. Async RPC с обратным вызовом по HTTP
- 26. Java, метод с обратным вызовом считается async?
- 27. проблема с обратным вызовом node.js
- 28. Помощь с обратным вызовом JQuery
- 29. Синхронизация Java с обратным вызовом
- 30. Проблемы с обратным вызовом chrome.serial.connect
Что контекст этой операции? Внутри веб-страницы? – Keltex
Такая вещь почти тривиальна в F #. Возможно, стоит написать модуль в F #, который можно вызвать из кода C# ... –
@Keltex он будет частью веб-приложения. – aepheus