.NET 4.5 轮询进度示例请

.NET 4.5 Polling Progress Example Please

我想在 windows 服务中异步 运行 一个较长的 运行ning 进程 - 并每 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";
}

您可以使用 Reactive Extensions (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 的更多信息