我真正想做的就是完成两个异步操作,一个接一个。 E.g。
下载网站X.完成后,下载网站Y。
答案 0 :(得分:2)
从两个observable中执行SelectMany(使用ToAsync将操作作为IObservables),就像LINQ选择多个(或使用语法糖):
var result =
from x in X
from y in Y
select new { x, y }
还有其他选择,但这取决于您的具体情况。
答案 1 :(得分:1)
我自己不喜欢这样的建议,但是......
如果您需要按顺序执行两个操作,请按顺序执行(您仍然可以在与main不同的线程上执行这些操作)。
如果您仍想在代码中分离任务,那么System.Parallel中的新构造将是合适的:
var task1 = Task.Factory.StartNew (() => FirstTask());
var task2 = task1.ContinueWith (frst => SecondTask ());
如果这是一种grok system.reactive的方法,请尝试Observable.GenerateInSequence - 但它肯定会有点过分。请记住,observable是可枚举的对应物,它最好以类似的方式使用(迭代数据)。它不是运行异步操作的工具。
编辑:我想承认我错了,理查德是对的 - 在我的回复时我对RX不太满意。现在我认为RX是启动异步操作的最自然方式。然而,理查德的答案有点吝啬,应该是:
var result =
from x in XDownload.ToAsync()()
from y in YDownload.ToAsync()()
select y
答案 2 :(得分:1)
可能还有以下几点:
static IObservable<DownloadProgressChangedEventArgs> CreateDownloadFileObservable(string url, string fileName)
{
IObservable<DownloadProgressChangedEventArgs> observable =
Observable.CreateWithDisposable<DownloadProgressChangedEventArgs>(o =>
{
var cancellationTokenSource = new CancellationTokenSource();
Scheduler.TaskPool.Schedule
(
() =>
{
Thread.Sleep(3000);
if (!cancellationTokenSource.Token.IsCancellationRequested)
{
WebClient client = new WebClient();
client.DownloadFileAsync(new Uri(url), fileName,fileName);
DownloadProgressChangedEventHandler prgChangedHandler = null;
prgChangedHandler = (s,e) =>
{
o.OnNext(e);
};
AsyncCompletedEventHandler handler = null;
handler = (s, e) =>
{
prgChangedHandler -= prgChangedHandler;
if (e.Error != null)
{
o.OnError(e.Error);
}
client.DownloadFileCompleted -= handler;
o.OnCompleted();
};
client.DownloadFileCompleted += handler;
client.DownloadProgressChanged += prgChangedHandler;
}
else
{
Console.WriteLine("Cancelling download of {0}",fileName);
}
}
);
return cancellationTokenSource;
}
);
return observable;
}
static void Main(string[] args)
{
var obs1 = CreateDownloadFileObservable("http://www.cnn.com", "cnn.htm");
var obs2 = CreateDownloadFileObservable("http://www.bing.com", "bing.htm");
var result = obs1.Concat(obs2);
var subscription = result.Subscribe(a => Console.WriteLine("{0} -- {1}% complete ",a.UserState,a.ProgressPercentage), e=> Console.WriteLine(e.Message),()=> Console.WriteLine("Completed"));
Console.ReadKey();
subscription.Dispose();
Console.WriteLine("Press a key to exit");
Console.ReadKey();
}
您可以将CreateDownloadFileObservable转换为WebClient上的扩展方法,并删除方法定义中的WebClient client = new WebClient();
,然后客户端woudl如下所示:
WebClient c = new WebClient();
c.CreateDownloadFileObservable ("www.bing.com","bing.htm");