Здравствуйте, _NN_, Вы писали:
_NN>Насколько актуально использование Reactive Extensions сегодня ? _NN>Чем пользуетесь вы ?
Как то использовал его в WinPhone 7 еще до того, как там появилась поддержка Task. Иначе там было сложно, вот тут описание: http://rsdn.org/forum/dotnet/4695296.all
Т.е. Rx заставила использовать кривая платформа. Думаю что из-за этой кривизны и усложнизма она и провалилась.
С тех пор никогда в жизни и намеков не было на задачи, где бы Rx был хоть сколько нибудь полезен. Если вы встречались на практике с такими задачами — хотелось бы услышать. Помоему абсолютно бесполезная хрень.
D>Немножко поигрался с этим, для чего хотите использовать?
Для работы, как для чего.
Пару лет назад использовал для удобной обработки данных.
С тех пор появились асинхронные потоки и остальные прелести во фреймворке.
Вот и вопрос есть ли ещё место для Rx в современном мире или что его заменяет.
Здравствуйте, Shmj, Вы писали:
S>Вопрос как раз в том, кто и для чего использует. Зачем столько людей делают хрень, которая никому не нужна?
Я не использую из-за специфики текущего окружения.
Но когда-то давно использовал в кровавом энтерпрайзе, просто как замену обычным .NET-ивентам. Это удобнее тем, что правильно организована отписка от события: при подписке возвращается IDisposable-токен. В то время как от обычных .NET-ивентов нельзя просто так взять и отписаться.
Здравствуйте, Shmj, Вы писали:
S>С тех пор никогда в жизни и намеков не было на задачи, где бы Rx был хоть сколько нибудь полезен. Если вы встречались на практике с такими задачами — хотелось бы услышать. Помоему абсолютно бесполезная хрень.
Каким образом решается передача данных асинхронно с фильтрами и обработчиками ?
Скажем в Rx легко написать что то вроде observable.Buffer(..).Scan(..).Throttle(..).Where(..) https://gist.github.com/danielmoore/1182831
А как это делается сегодня без этой библиотеки ?
.
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, _NN_, Вы писали:
_NN>>А как это делается сегодня без этой библиотеки ?
S>Чем не устраивают Task/async/await?
Устраивают конечно, но не всё легко выражается через одни async/await:
Например какие тут варианты реализации вместо Observable ?
var fsw = new FileSystemWatcher(@"C:\")
{
IncludeSubdirectories = true,
EnableRaisingEvents = true
};
var changes = from c in Observable.FromEventPattern<FileSystemEventArgs>(fsw, "Changed")
select c.EventArgs.FullPath;
changes.Window(TimeSpan.FromSeconds(5)).Subscribe(async window =>
{
var count = await window.Count();
Console.WriteLine("{0} events last 5 seconds", count);
});
S>С тех пор никогда в жизни и намеков не было на задачи, где бы Rx был хоть сколько нибудь полезен. Если вы встречались на практике с такими задачами — хотелось бы услышать. Помоему абсолютно бесполезная хрень.
Очень простая задача встречающаяся практически в любом интерфейсе — нужно отобразить список Items[] GetList(string filter) который формируется долго, задержка плавающая т.е. может от 0.1 секунды ответ прийти до 5 секунд, пользователь вводит данные в поле filter, запрос сразу отправлять не требуется, только после 500 миллисекунд после того как пользователь перестал вводить данные. Нужно отображать актуальный список в UI соотвествующий последнему введеному filter.
Теперь напиши решение этой задачи на async/await.
Потом немного усложним условие — есть еще Checkbox который также отвечает за алгоритм фильтрации ( например Ignore Case в фильтре ).
Доработай решение на async/await чтобы также учитывать изменение Checkbox ( по той же логике что и изменение строки 500 мс игнорим событие потом продолжаем если пользователь ничего не менят ).
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Здравствуйте, okon, Вы писали:
O>Очень простая задача встречающаяся практически в любом интерфейсе — нужно отобразить список Items[] GetList(string filter) который формируется долго, задержка плавающая т.е. может от 0.1 секунды ответ прийти до 5 секунд, пользователь вводит данные в поле filter, запрос сразу отправлять не требуется, только после 500 миллисекунд после того как пользователь перестал вводить данные. Нужно отображать актуальный список в UI соотвествующий последнему введеному filter.
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, okon, Вы писали:
O>>Очень простая задача встречающаяся практически в любом интерфейсе — нужно отобразить список Items[] GetList(string filter) который формируется долго, задержка плавающая т.е. может от 0.1 секунды ответ прийти до 5 секунд, пользователь вводит данные в поле filter, запрос сразу отправлять не требуется, только после 500 миллисекунд после того как пользователь перестал вводить данные. Нужно отображать актуальный список в UI соотвествующий последнему введеному filter.
S>Примерно так (набросал идею):
S>
Тут уже в алгоритме ошибка: таймер ожидания должен сбрасываться после каждого нажатия клавиши, а у вас после первого нажатия через 500 мс запрос уйдёт в любом случае. Более того, я могу ошибаться, но запрос будет отправлен по всем нажатиям клавиш, потому что не делается проверка что асинхронная функция уже была вызвана.
Здравствуйте, Somescout, Вы писали:
S>Тут уже в алгоритме ошибка: таймер ожидания должен сбрасываться после каждого нажатия клавиши, а у вас после первого нажатия через 500 мс запрос уйдёт в любом случае.
Нет, т.к. после 500 мс ожидания идет проверка. Если была нажата клавиша — будет установлен флаг _changed и выход из функции.
if (_changed)
return;
S>Более того, я могу ошибаться, но запрос будет отправлен по всем нажатиям клавиш, потому что не делается проверка что асинхронная функция уже была вызвана.
Да, по тем что успели отправить — уже не отменяем.
Чтобы не гадать — запустите, это WinForms-приложение. 2 TextBox кинуть на форму и у первого TextBox подписка на textBox1_KeyUp.
S>>Тут уже в алгоритме ошибка: таймер ожидания должен сбрасываться после каждого нажатия клавиши, а у вас после первого нажатия через 500 мс запрос уйдёт в любом случае.
S>Нет, т.к. после 500 мс ожидания идет проверка. Если была нажата клавиша — будет установлен флаг _changed и выход из функции.
У вас после нажатия на клавишу сразу без ожидания будет вызвана функция FillItems, которая сразу же сбросит этот флаг.
S>>Более того, я могу ошибаться, но запрос будет отправлен по всем нажатиям клавиш, потому что не делается проверка что асинхронная функция уже была вызвана.
S>См. выше.
Здравствуйте, Somescout, Вы писали:
S>У вас после нажатия на клавишу сразу без ожидания будет вызвана функция FillItems, которая сразу же сбросит этот флаг.
Ваша правда. Без счетчика запросов не обойтись:
private volatile int _lastRequestId;
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
_lastRequestId++;
FillItems();
}
private async void FillItems()
{
var requestId = _lastRequestId;
await Task.Delay(500);
if (requestId != _lastRequestId)
return;
textBox2.Clear();
var items = await MakeRequest(textBox1.Text);
if (_lastRequestId != requestId)
return;
textBox2.Text = string.Join("\r\n", items);
}
Random _random = new Random();
private async Task<List<string>> MakeRequest(string q)
{
await Task.Delay(_random.Next(100, 5000));
return await Task.FromResult(new List<string>()
{
q + " пункт 1 ",
q + " пункт 2",
q + " пункт 3",
});
}
Еще вариант с отменой:
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
FillItems();
}
private CancellationTokenSource _cancelTokenSource;
private async void FillItems()
{
_cancelTokenSource?.Cancel(true);
var cancelTokenSource = new CancellationTokenSource();
_cancelTokenSource = cancelTokenSource;
try
{
await Task.Delay(500, cancelTokenSource.Token);
textBox2.Clear();
var items = await MakeRequest(textBox1.Text, cancelTokenSource.Token);
textBox2.Text = string.Join("\r\n", items);
}
catch (TaskCanceledException)
{
}
}
Random _random = new Random();
private async Task<List<string>> MakeRequest(string q, CancellationToken cancellationToken)
{
await Task.Delay(_random.Next(100, 5000), cancellationToken);
Console.Beep(1000, 10);
return await Task.FromResult(new List<string>()
{
q + " пункт 1 ",
q + " пункт 2",
q + " пункт 3",
});
}
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, okon, Вы писали:
O>>Очень простая задача встречающаяся практически в любом интерфейсе — нужно отобразить список Items[] GetList(string filter) который формируется долго, задержка плавающая т.е. может от 0.1 секунды ответ прийти до 5 секунд, пользователь вводит данные в поле filter, запрос сразу отправлять не требуется, только после 500 миллисекунд после того как пользователь перестал вводить данные. Нужно отображать актуальный список в UI соотвествующий последнему введеному filter.
S>, 5000)); S> return await Task.FromResult(new List<string>() S> { S> q + "пункт 1 ", S> q + "пункт 2", S> q + "пункт 3", S> }
Только стандартный баг ты сделал в таком решении, то что если предыдущий запрос будет дольше чем новый то старый запрос перетрет данные и они будут не релевантны фильтру
Поиграйся с этим решением, заметишь баг.
O>>Потом немного усложним условие — есть еще Checkbox который также отвечает за алгоритм фильтрации ( например Ignore Case в фильтре ).
S>И чем это усложнит?
Да тут нужнл еще условие что с чек боксом должен другой метод "сервиса" вызываться.
Попробуй.
Потом посмотри как просто и элегантно подобная задача решается в парадигме RX.
Она обычно есть в разных примерах.одна строка.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Здравствуйте, okon, Вы писали:
O>Только стандартный баг ты сделал в таком решении, то что если предыдущий запрос будет дольше чем новый то старый запрос перетрет данные и они будут не релевантны фильтру O>Поиграйся с этим решением, заметишь баг.
Здравствуйте, okon, Вы писали:
O>Потом посмотри как просто и элегантно подобная задача решается в парадигме RX. O>Она обычно есть в разных примерах.одна строка.
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, okon, Вы писали:
O>>Потом посмотри как просто и элегантно подобная задача решается в парадигме RX. O>>Она обычно есть в разных примерах.одна строка.
S>Я привел пример
inputObservable
.Throttle(500)
.CombineLatest(input => GetList(input))
.OnNext( result => texbBox.text = result );
Ну и по событию кидать в inputObservable новые данные
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов