我想在windows服务中异步运行一个长时间运行的进程,每3秒轮询一次进程,并使用SignalR进行报告。下面的代码(理论上)将以一种基于事件的方式来实现这一点,但我不想每一次更改都会激发进度。
请有人提供一个简单的例子,说明如何具体实施,以启动流程并轮询/报告进度。请记住,我已经离开全职发展几年了!
public async Task<string> StartTask(int delay)
{
var tokenSource = new CancellationTokenSource();
var progress = new Progress<Tuple<Int32, Int32>>();
progress.ProgressChanged += (s, e ) =>
{
r2hProcessesProxy.Invoke("DownloadNotify", string.Format("Major={0} - Minor={1}", e.Item1 , e.Item2 ));
};
var task = DownloadTask.DoDownload(delay, tokenSource.Token, new Progress<Tuple<Int32,Int32>>(p => new Tuple<Int32, Int32>(0,0)));
await task;
return "Task result";
}
您可以使用反应扩展(Rx)来实现这一点。检查Throttle()
方法:https://msdn.microsoft.com/en-us/library/hh229400(v=vs.103).aspx
using System;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
public class Test
{
public async Task<string> StartTask(int delay)
{
var tokenSource = new CancellationTokenSource();
var progress = new Progress<Tuple<Int32, Int32>>();
var observable = Observable.FromEvent<EventHandler<Tuple<Int32, Int32>>, Tuple<Int32, Int32>>(h => progress.ProgressChanged += h, h => progress.ProgressChanged -= h);
var throttled = observable.Throttle(TimeSpan.FromSeconds(3));
using (throttled.Subscribe(e =>
{
r2hProcessesProxy.Invoke("DownloadNotify", string.Format("Major={0} - Minor={1}", e.Item1, e.Item2));
}))
{
await DownloadTask.DoDownload(delay, tokenSource.Token, new Progress<Tuple<Int32, Int32>>(p => new Tuple<Int32, Int32>(0, 0)));
}
return "result";
}
}
检查http://go.microsoft.com/fwlink/?LinkId=208528有关RX 的更多信息