如果外部库仅提供注册回调而不是事件,那么从中创建Observable
的最佳方法是什么?
如果它是我可以使用Observable.FromEventPattern
的事件,但在这种情况下,我唯一的想法就是在每次回调时使用Subject
并在其中排队事件。
有没有更好的方法呢?
答案 0 :(得分:5)
使用Observable.Create
.以下是一个例子:
void Main()
{
var target = new SampleCallbacker();
var actionB = new Action<int>(i => Console.WriteLine($"{i} * {i} = {i * i}."));
target.Register(actionB);
var observable = Observable.Create<int>(observer =>
{
var action = new Action<int>(i => observer.OnNext(i));
target.Register(action);
return () => target.Unregister(action);
});
var subscription = observable.Subscribe(i => Console.WriteLine($"From observable: {i} was fired."));
target.Fire(1);
target.Fire(2);
target.Fire(3);
Console.WriteLine("Unsusbscribing observable...");
subscription.Dispose();
target.Fire(4);
target.Fire(5);
}
class SampleCallbacker
{
private List<Action<int>> _actions = new List<System.Action<int>>();
public void Register(Action<int> action)
{
_actions.Add(action);
}
public void Unregister(Action<int> action)
{
while (_actions.Remove(action))
{} //loop remove
}
public void Fire(int i)
{
foreach (var action in _actions)
{
action(i);
}
}
}
答案 1 :(得分:0)
如果它是单个回调(例如,等待对查询的回复),那么您也可以使用StartAsync
方法。大多数现代API都可能支持任务/承诺。
Observable.StartAsync<string>(cancellation =>
{
var source = new TaskCompletionSource<string>();
yourlib.RegisterCallback(source.SetResult);
cancellation.Register(() => yourlib.UnregisterCallback(source.SetResult));
return source.Task;
});
如果您想避免多次订阅,您可以随时使用.Publish().RefCount()
共享一个订阅,当没有订阅者时,该订阅会被处理掉。
答案 2 :(得分:-1)
创建一个触发事件并将该方法作为回调传递的方法。