Выполняю множество последовательных get-запросов. Слать запросы можно не чаще, чем через 340 мс.
Каждый раз, когда поток доходит до get-запроса, нужно проверять, прошло ли 340 мс с последнего запроса. Если да, то делаем запрос, если нет - ждем и продолжаем.
Я сделал таймер, который запускается каждый раз после get-запроса, по истечении 340 мс выключается и делает запрос доступным с помощью bool переменной.
Код:
static class RequestTimer
{
public static bool requestIsAvailable;
public static Timer requestTimer;
static RequestTimer()
{
requestTimer = new Timer(340);
requestTimer.Elapsed += OnTimedEvent;
requestTimer.AutoReset = true;
requestTimer.Enabled = false;
requestIsAvailable = true;
}
private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
requestIsAvailable = true;
requestTimer.Enabled = false;
}
}
public class VkRequest
{
public string GetResponse(string url, string namesValues)
{
string result = null;
for (bool inLoop = true; inLoop == true; )
{
if (!RequestTimer.requestIsAvailable) continue;
RequestTimer.requestIsAvailable = false;
using (var client = new WebClient())
{
client.Encoding = Encoding.UTF8;
result = client.UploadString(url, namesValues);
RequestTimer.requestTimer.Enabled = true;
}
inLoop = false;
}
return result;
}
}
Понимаю, что решение мягко говоря не очень. Про ожидание зацикливанием я вообще молчу.
Читал про события, делегаты, async, await и т.д. Глаза разбегаются и нe могу понять, что конкретно лучше применять в моем случае.
Хотелось бы услышать какие-нибудь советы)
Если все запросы приходят в одном потоке, я бы сделал так:
Task cooldownTask = Task.CompletedTask;
Task currentRequest = null;
async Task<string> RequestAfterCooldown(string url, string namesValues)
{
// дождаться окончания предыдущих заданий
while (currentRequest != null)
await currentRequest;
// загеристрировать текущее задание
TaskCompletionSource<bool> thisRequest = new TaskCompletionSource<bool>();
currentRequest = thisRequest.Task;
try
{
// выдержать сделать паузу
await cooldownTask;
// установить новую паузу для следующего запроса
cooldownTask = Task.Delay(340);
// сделать сам запрос и вернуть ответ асинхронно
using (var client = new WebClient() { Encoding = Encoding.UTF8 })
return await client.UploadStringTaskAsync(url, namesValues);
}
finally
{
// завершить текущий запрос для тех, кто дожидается его снаружи
currentRequest = null;
thisRequest.SetResult(true);
}
}
Необходимо написать программу для отображения данных из буфера обмена (для проверки сохранения объектов)
Проблема при отслеживании электронной торговли в google analytics, данные передаются через measurment protocolФормат запросов следующий: передача транзакции...