我有一种情况,我需要使用自定义调度程序来运行任务(这些必须是任务)并且调度程序没有设置同步上下文(所以我收集了 no ObserveOn
,SubscribeOn
等)。SynchronizationContextScheduler
以下是我最终如何做到的。现在,我想知道,我不确定这是否是进行异步调用并等待其结果的最合适方式。这是可以的还是有更健壮或惯用的方式?
var orleansScheduler = TaskScheduler.Current;
var someObservable = ...;
someObservable.Subscribe(i =>
{
Task.Factory.StartNew(async () =>
{
return await AsynchronousOperation(i);
}, CancellationToken.None, TaskCreationOptions.None, orleansScheduler);
});
如果不需要等待怎么办?
<编辑:我找到了一个具体的简化示例来说明我在这里所做的事情。基本上我在奥尔良使用 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 论坛上相关主题的链接。