問題:我們有一些IP地址,那麼我們應該按照用戶指定的時間間隔來ping每一個,例如每400ms ping 192.168.0.1,每隔40000ms ping 192.168.137.20等等......我們如何以異步的方式處理這種情況?處理大量的異步作業
這是我從數據庫中加載目標信息,並創建一個傳感器爲他們每個人:
public class PingService
{
private CancellationTokenSource _cancel;
private List<PingSensor> _pings;
private IRepository<IPDevice> _deviceRepository;
public PingService()
{
_cancel = new CancellationTokenSource();
_pings = new List<PingSensor>();
_deviceRepository = ObjectFactory.GetInstance<IRepository<IPDevice>>();
}
public void Start()
{
Action act = new Action(() =>
{
IQueryable<IPDevice> allDevices = _deviceRepository.GetAll();
foreach (IPDevice device in allDevices)
{
PingResultCollector collector = new PingResultCollector(device);
_pings.Add(new PingSensor(device.Address, collector, device.CheckDuration, _cancel.Token));
}
foreach (PingSensor _ping in _pings)
{
_ping.DoDiscovery();
}
});
Task.Factory.StartNew(act);
}
public void Stop()
{
_cancel.Cancel();
}
}
,這是我們做平,並等待用戶指定的延遲,收集響應和.. 。
public class PingSensor
{
private string _address;
Ping _ping;
private bool lastRequestReplayed;
private int _delay;
private CancellationToken _cancellationToken;
private PingResultCollector _resultCollector;
public PingSensor(string address, PingResultCollector resultCollector, int delay, CancellationToken CancellationToken)
{
_address = address;
_cancellationToken = CancellationToken;
_ping = new Ping();
_resultCollector = resultCollector;
_ping.PingCompleted += _ping_PingCompleted;
_delay = delay;
}
void _ping_PingCompleted(object sender, PingCompletedEventArgs e)
{
if (_cancellationToken.IsCancellationRequested)
return;
lastRequestReplayed = true;
//_eventHandler(sender, e);
if (_resultCollector != null)
_resultCollector.CollectData(new PingStatus()
{
PingStatusId = Guid.NewGuid(),
Address = e.Reply == null ? "" : e.Reply.Address.ToString(),
Status = e.Reply == null ? e.Error.Message : e.Reply.Status.ToString(),
Target = e.UserState.ToString(),
ResponseTime = e.Reply == null ? 0 : e.Reply.RoundtripTime,
UpdateTime = DateTime.UtcNow
});
}
public void DoDiscovery()
{
lastRequestReplayed = true;
Action act = new Action(() =>
{
while (_cancellationToken.IsCancellationRequested!=true)
{
if (_cancellationToken.IsCancellationRequested)
return;
byte[] data = new byte[2];
if (lastRequestReplayed)
{
_ping.SendAsync(_address, 30000, data, _address);
lastRequestReplayed = false;
}
if (_cancellationToken.IsCancellationRequested)
return;
Thread.Sleep(_delay);
if (_cancellationToken.IsCancellationRequested)
return;
}
});
Task.Factory.StartNew(act);
}
}
以及與此代碼的問題是它創建每個傳感器一個線程,這意味着如果我有500目標萍我也有500個線程!任何建議?和我的英語不好很抱歉:d
一個重要的說明,這_將不會啓動500個線程。這將**排隊** 500個任務,運行時將根據代碼運行的環境決定有多少線程適合執行,但是是一個'Task'!=線程。所以,如果你真的需要這500個任務,並行運行,那麼這可能不是一個好的解決方案。 – CodingGorilla 2014-11-05 20:22:18
thx您的評論,我明白,我沒有測試它真的有500個任務,但對於70個目標我得到70個線程,這正是我的問題,一些任務彎腰很長時間,它可能需要30秒一個任務再次工作 – cyberw0lf 2014-11-05 20:33:05
您是否可以選擇使用.Net 4.5? – 2014-11-05 20:47:44