У меня есть ситуация, когда мне нужно использовать собственный планировщик для запуска задач (это должны быть задачи), и планировщик не устанавливает контекст синхронизации (поэтому нет ObserveOn
, SubscribeOn
, SynchronizationContextScheduler
и т. Д. Я собираюсь). Вот как я это сделал. Теперь, мне интересно, я не уверен, что это самый подходящий способ делать асинхронные вызовы и ждать их результатов. Это все в порядке или есть более надежный или идиоматический способ?Является ли вообще сомнительным вызов Task.Factory.StartNew (async() => {}) в Subscribe?
var orleansScheduler = TaskScheduler.Current;
var someObservable = ...;
someObservable.Subscribe(i =>
{
Task.Factory.StartNew(async() =>
{
return await AsynchronousOperation(i);
}, CancellationToken.None, TaskCreationOptions.None, orleansScheduler);
});
Что делать, если ожидание не понадобится?
< редактировать: Я нашел бетон и упрощенный пример того, что я делаю here. В основном я использую Rx в Орлеане, и приведенный выше код - это голые иллюстрации того, что я делаю. Хотя меня тоже интересует эта ситуация в целом.
Окончательный код Получается, что это было немного сложно в контексте Орлеана. Я не вижу, как я мог бы использовать ObserveOn
, что было бы просто тем, что я хотел бы использовать. Проблема в том, что при использовании этого параметра Subscribe
никогда не будет вызван. Код:
var orleansScheduler = TaskScheduler.Current;
var factory = new TaskFactory(orleansScheduler);
var rxScheduler = new TaskPoolScheduler(factory);
var someObservable = ...;
someObservable
//.ObserveOn(rxScheduler) This doesn't look like useful since...
.SelectMany(i =>
{
//... we need to set the custom scheduler here explicitly anyway.
//See Async SelectMany at http://log.paulbetts.org/rx-and-await-some-notes/.
//Doing the "shorthand" form of .SelectMany(async... would call Task.Run, which
//in turn runs always on .NET ThreadPool and not on Orleans scheduler and hence
//the following .Subscribe wouldn't be called.
return Task.Factory.StartNew(async() =>
{
//In reality this is an asynchronous grain call. Doing the "shorthand way"
//(and optionally using ObserveOn) would get the grain called, but not the
//following .Subscribe.
return await AsynchronousOperation(i);
}, CancellationToken.None, TaskCreationOptions.None, orleansScheduler).Unwrap().ToObservable();
})
.Subscribe(i =>
{
Trace.WriteLine(i);
});
Кроме того, ссылка на соответствующую резьбу в Codeplex Orleans forums.
'ожидание в порядке не понадобится'. Не могли бы вы пояснить, что это значит? –
Если операция асинхронна, почему вы используете для нее поток threadpool? –
Я удалил упоминание «в порядке» и очистил некоторые другие моменты. – Veksi