C# 使用计时器获取并行请求
我有这个场景。我有一个计时器(autoreset=true),每隔2秒执行一次,当计时器触发时,它将调用10个不同的URL来收集数据。每次平均1秒 我在parallel.foreach循环中运行了这个过程,但是发生的是大多数调用返回得很快,但随机返回的一些调用将花费更长的时间。然后,获取所有10个请求所需的总时间是10秒 下一个事件不会触发,直到并行请求全部完成,计时器才能重试,因此理论上它不是每2秒轮询一次URLC# 使用计时器获取并行请求,c#,timer,parallel.foreach,C#,Timer,Parallel.foreach,我有这个场景。我有一个计时器(autoreset=true),每隔2秒执行一次,当计时器触发时,它将调用10个不同的URL来收集数据。每次平均1秒 我在parallel.foreach循环中运行了这个过程,但是发生的是大多数调用返回得很快,但随机返回的一些调用将花费更长的时间。然后,获取所有10个请求所需的总时间是10秒 下一个事件不会触发,直到并行请求全部完成,计时器才能重试,因此理论上它不是每2秒轮询一次URL public List<string> Urls {get;set;
public List<string> Urls {get;set;}
private Timer SetupTimer()
{
var timer = new Timer(2000);
timer.AutoReset = false;
timer.Elapsed += timer_Elapsed;
timer.Start();
return timer;
}
private async void timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
Parallel.ForEach(Urls, url=>
{
var data= _dataService.GetData(url);
SetOnDataRecieved(new DataRecievedEventArgs(data));
});
}
finally
{
if (timer == null) return;
if (!timer.Enabled) { timer.Enabled = true; }
timer.Start();
}
}
公共列表URL{get;set;}
专用定时器SetupTimer()
{
var定时器=新定时器(2000);
timer.AutoReset=false;
timer.appeated+=timer\u appeated;
timer.Start();
返回计时器;
}
专用异步无效计时器(对象发送器,ElapsedEventArgs e)
{
尝试
{
Parallel.ForEach(url,url=>
{
var data=\u dataService.GetData(url);
SetOnDataReceived(新数据ReceiveDeventargs(数据));
});
}
最后
{
if(timer==null)返回;
如果(!timer.Enabled){timer.Enabled=true;}
timer.Start();
}
}
有什么更好的方法来实现这一点?谢谢。除非所有等待最慢的URL都有问题,否则您的实现本身没有什么问题。您可以实现一个封装所有程序逻辑的类,并且一次只连接到一个URL。这样,没有一个URL会阻止其他URL。将尽可能快地检索每个URL,然后继续两秒钟的等待。类似的方法可能会起作用(未经测试):
你能和我分享一些代码吗,你已经试着让它工作了吗?谢谢,我会尝试一下,希望它能满足我的需要。
public class UrlWatcher
{
public string Url { get; set; }
Timer timer { get; set; } = new Timer();
DataService _dataService { get; set; }
//Todo: Implement CancellationToken to gracefully stop the timer.
//Event to report retrieved data
public EventHandler<DataReceivedEventArgs> OnDataReceived;
public UrlWatcher(string Url, int TimerInterval = 2000)
{
//Use your implementation of DataService() here
_dataService = new DataService();
this.Url = Url;
timer.AutoReset = false;
timer.Interval = TimerInterval;
}
public void Start() // Call this to start polling the URL
{
timer.Start();
}
public async void timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
var data = await _dataService.GetData(Url);
OnDataReceived(this, new DataReceivedEventArgs(data));
}
finally
{
if (timer != null && !timer.Enabled)
{
timer.Enabled = true;
timer.Start();
}
}
}
}
//Thread-safe collection to hold results
ConcurrentBag<string> results { get; set; } = new ConcurrentBag<string>();
List<string> urls { get; set; } = new List<string>() { "www.google.com", "www.facebook.com", "www.yahoo.com" };
//List to hold URL watchers
List<UrlWatcher> watchers { get; set; } = new List<UrlWatcher>();
private void StartBtn_Click(object sender, EventArgs e)
{
//Create a separate watcher for each URL. Subscribe to the OnDataReceived event. Start the watchers.
foreach(var url in urls)
{
UrlWatcher w = new UrlWatcher(url);
w.OnDataReceived += (o, oe) => results.Add(oe.CollectedData);
w.Start();
watchers.Add(w);
}
}