У меня есть кнопка, которая открывает чат-бота в браузере. Проблема в том, что у меня нет прямого адреса для чата. Я должен запросить у второго сервера этот адрес, чтобы моя кнопка не реагировала сразу на нажатие.
Я бы хотел, чтобы он не открывал две вкладки браузера, если кнопка нажимается дважды довольно быстро. Мне нужно что-то, похожее на Throttle, но вместо проверки истекшего времени, проверяется, завершилось ли предыдущее событие, которое позволяет go, или нет.
Полагаю, я мог бы сделать это с логическим значением проверка и фильтр в реактивном конвейере, но я не хочу иметь дело с безопасностью потока на этом логическом значении, так как я запускаю процесс во втором потоке.
Например, у меня есть метод, который делает что-то длинное, например, вызывает API для получения адреса:
private async Task<string> LongTask()
{
await Task.Delay(1000);
return "a return value";
}
И я бы хотел обрабатывать его одним кликом за раз, сбрасывая любые другие щелчки, которые происходят до того, как первое событие завершило обработку, немного похожи на:
var longTaskObservable =
Observable.FromAsync(LongTask) // Create observable from async method that returns one value
.SubscribeOn(NewThreadScheduler.Default); // Run it on a background thread
bool inProgress = false;
Observable.FromEventPattern(btn, "Click") // On a click event
.Where(_ => !inProgress)
.Do(_ => inProgress = true)
.SelectMany(longTaskObservable) // Start the long task observable and use its unwrapped values instead of the event args
.Where(s => !string.IsNullOrEmpty(s)) // Exclude any results that are marked as invalid
.ObserveOnDispatcher() // Set the thread of the subscribe method after to the ui thread
.Subscribe(result => {
LogWithThread("Got result '" + result + "' on thread {0}");
inProgress = false;
}); // Get the result
Но это не очень чисто, не ясно и не модульно, и его легко сломать. Кажется, что это должно быть так просто ... Я, должно быть, что-то здесь упускаю.
Любая помощь будет высоко ценится! Спасибо