If you do in the console, it works normally (code 1), and if it does not output for a form (code 2, 3). What to do here?

public static void PingMethod() { var urles = new List<string> ( Properties.Resources.proxylist.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries) ); var goodUrls = new List<string>(); var badUrls = new List<string>(); var timeout = 1; var sync = new object(); var counter = urles.Count; var isReady = new ManualResetEvent(false); foreach (var ur in urles) { var _url = ur.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries); var u = _url[0]; var url = u; var ping = new Ping(); ping.PingCompleted += (s, e) => { lock (sync) { ping.Dispose(); if (e.Reply.Status == IPStatus.Success) { goodUrls.Add(ur); } else { badUrls.Add(url); } if (--counter == 0) { isReady.Set(); } } }; ping.SendAsync(u, timeout, null); } isReady.WaitOne(); Console.WriteLine("Good Urls"); foreach (var u in goodUrls) { Console.WriteLine(u); } Console.WriteLine(""); Console.WriteLine("Bad Urls"); foreach (var u in badUrls) { Console.WriteLine(u); } Console.WriteLine("goodUrls " + goodUrls.Count); Console.WriteLine("badUrls " + badUrls.Count); Console.ReadKey(); } 

For forms, a similar method:

  public static List<string> PingTwoMethod() { List<string> urles = new List<string>(Properties.Resources.proxylist_at_15_10_2015.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)); List<string> goodUrls = new List<string>(); List<string> badUrls = new List<string>(); int timeout = 1; Object sync = new object(); int counter = urles.Count; ManualResetEvent isReady = new ManualResetEvent(false); foreach (var ur in urles) { string[] _url = ur.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries); string u = _url[0]; string url = u; Ping ping = new Ping(); ping.PingCompleted += (s, e) => { lock (sync) { ping.Dispose(); if (e.Reply.Status == IPStatus.Success) { goodUrls.Add(url); } else { badUrls.Add(url); } if (--counter == 0) { isReady.Set(); } } }; ping.SendAsync(url, timeout, null); List<string> good = new List<string>(goodUrls); return good; } //isReady.WaitOne(); return goodUrls; } 

and a button on the form:

  private void button1_Click(object sender, EventArgs e) { List<string> goods = new List<string>(); goods = Pings.PingMethod(); if (goods != null) { foreach (var item in goods) { richTextBox1.Text += item; } } else { richTextBox1.Text += "Пусто"; } } 

    2 answers 2

    Do not use outdated API. Work through Task , multithreaded problems will go away by themselves.

    For example:

     public async static Task<List<string>> Ping(List<string> ips) { List<string> goodIps = new List<string>(); List<string> badIps = new List<string>(); Ping ping = new Ping(); foreach (var ipAndPort in ips) { var ip = ipAndPort.Split(':')[0]; var answer = await ping.SendPingAsync(ip, timeout); if (answer.Status == IPStatus.Success) goodIps.Add(ipAndPort); else badIps.Add(ipAndPort); } return goodIps; } 

    And the code has become much clearer.

    If we want to ping everything at the same time , we do this:

     public async static Task<List<string>> Ping(List<string> ips) { List<string> goodIps = new List<string>(); List<string> badIps = new List<string>(); Ping ping = new Ping(); var tasks = ips.Select(ipAndPort => { var ip = ipAndPort.Split(':')[0]; return ping.SendPingAsync(ip, timeout); }).ToList(); var results = await Task.WhenAll(tasks); foreach (var answer in results) { if (answer.Status == IPStatus.Success) goodIps.Add(ipAndPort); else badIps.Add(ipAndPort); } return goodIps; } 

    Calling now is simple:

     var allIps = ...; var goodIps = await Ping(allIps); if (goodIps.Count == 0) richTextBox.Text = "Все плохие"; else richTextBox.Text = string.Join("\n", goodIps); 
    • your code is not compiled, so corrected is compiled: - pontekorvo
    • @pontekorvo: Quite possibly, wrote on my knee. - VladD
    • Thanks for the quick response, first fixed: public async static Task <List <string >> Ping (List <string> ips) and this: if (answer.Status == IPStatus.Success) and the last one, but since type of output has changed, it is now unclear how to display on the screen. About this Task <List <string >> I can not find anything. - pontekorvo
    • @pontekorvo: Okay, corrected the answer text. The output type has not changed in fact, maybe you forgot await ? Show the calling code. - VladD
    • Something is wrong with this code - only one iteration in foreach () passes. - pontekorvo

    An example of VladD works in this form, but more slowly than the one proposed in the question.

     public async static Task<List<string>> Ping(List<string> ips) { List<string> goodIps = new List<string>(); List<string> badIps = new List<string>(); var timeout = 1; Ping ping = new Ping(); foreach (var ipAndPort in ips) { var ip = ipAndPort.Split(':')[0]; var answer = await ping.SendPingAsync(ip, timeout); if (answer.Status == IPStatus.Success) goodIps.Add(ipAndPort); else badIps.Add(ipAndPort); } return goodIps; } static void Main(string[] args) { Example(); Console.ReadKey(); } static async void Example() { var allIps = new List<string>(Properties.Resources.proxylist.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)); var goodIps = await PingThree.Ping(allIps); if (goodIps.Count == 0) Console.WriteLine("Все плохие"); else foreach (var item in goodIps) { Console.WriteLine(item); } }