我坚持正确处理在应用程序退出时使用RX创建的线程。我在Process Explorer中看到,在应用程序关闭后,线程仍在运行,导致IO异常。
class Program
{
static void Main(string[] args)
{
CompositeDisposable subsriptions = new CompositeDisposable();
subscriptions.Add(Observable.Interval(TimeSpan.FromSeconds(15))
.Subscribe(_ =>
{
getData();
}));
Thread.Sleep(TimeSpan.FromSeconds(20));
subscriptions.Dispose();
}
}
}
如果您看到我取消注释subscription.Dispose(),则线程终止而不获取任何数据。任何帮助,将不胜感激。感谢
答案 0 :(得分:1)
您需要subsriptions.Add(...)
和subscriptions.Dispose()
之间的某种延迟。在那之间没有延迟,您的应用程序只是简单地订阅并立即处理它们,没有时间让线程完成他们的工作。 (并且Thread.Sleep(1000)
不起作用,因为它在订阅函数内部,而不是主函数的一部分。)
答案 1 :(得分:1)
您正在寻找的模式与此类似
class Program {
public string GetData(){
return "Hello";
}
public string async GetDataAsync(){
return await Observable
.Interval(TimeSpan.FromSeconds(15))
.Take(1)
.Select(()=>GetData());
}
static void Main(string[]args){
var s = GetDataAsync().Wait();
}
}
Wait
的原因是在这种情况下不能使用入口点Main
标记为async
。 Wait
阻止当前线程,直到Task返回
由GetDataAsync
生成一个值。
另请注意,IObservable与async / await兼容,并将返回最后一个
序列产生的值。这就是我添加Take(1)
的原因
只有1个滴答。
另一种选择就是直接在IObservable上调用Wait,就像在
中一样class Program {
public string GetData(){
return "Hello";
}
public IObservable<string> GetDataObservable(){
return Observable
.Interval(TimeSpan.FromSeconds(15))
.Take(1)
.Select(()=>GetData());
}
static void Main(string[]args){
var s = GetDataObservable().Wait();
}
}
答案 2 :(得分:0)
您可以使用将取消基础任务执行的CancellationToken
订阅您的observable:
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Observable.
Interval(TimeSpan.FromSeconds(15)).
Subscribe(_ => getData(), cts.Token));
cts.CancelAfter(TimeSpan.FromSeconds(20));
}