C# возврат с потока

288
16 января 2019, 03:00
public static string pingAllChildren(string myIp)
        {
            object locker = new object();
            string res = string.Empty;
            for (int i = 1; i < 5; i++)
            {
                int j = i;
                Task.Run(async () =>
                {
                    string ip = myIp.Remove(myIp.LastIndexOf('.'), myIp.Length - myIp.LastIndexOf('.')) + $".{j + 10}";
                    IPStatus t = await pingAsync($"{ip}");
                    lock (locker)
                    {
                        res += $"{ip} : {t.ToString()}\n";
                    }
                }).Wait();
                //string ip = myIp.Remove(myIp.LastIndexOf('.'), myIp.Length - myIp.LastIndexOf('.')) + $".{j + 10}";
                //ThreadPool.QueueUserWorkItem(pingAsync(ip));
            }
            return res;
        }

если Wait() уберу, то возвратиться пустой результат. А так никакой асинхронности.

Как мне дождаться выполнения всех потоков, чтобы возвратить результат нормально?

Answer 1

На мой взгляд лучше было бы сделать так:

public static string pingAllChildren(string myIp)
{
    var pings = Enumerable.Range(1, 4).Select(i =>
             myIp.Remove(myIp.LastIndexOf('.'), myIp.Length - myIp.LastIndexOf('.')) + $".{i + 10}")
        .Select(ip => new { ip, task = pingAsync(ip) }).ToList();
    Task.WaitAll(pings.Select(p => p.task).ToArray());
    return string.Join(Environment.NewLine, pings.Select(p => $"{p.ip} : {p.task.Result}"));
}

Сначала создаем нужные нам IP и запускаем таску пинга. Помещаем это в анонимный объект, чтобы потом не потерять пингуемый IP. Далее происходит ожидание всех задач из массива и только после этого через string.Join мы создаем форматированный результат.

Answer 2
await Task.Run(async () => {
    // 
});
Answer 3

Прошу прощения, я не так понял задачу. Вашу проблему можно решить с помощью коллбеков, которые выполняются после завершения задачи.

 public static string pingAllChildren(string myIp)
    {
        List<Task> taskList = new List<Task>();
        object locker = new object();
        string res = string.Empty;
        Action<Task<string>> act = (Task<string> a) =>
            {
                res += a.Result;
            };
        for (int i = 1; i < 5; i++)
        {
            int j = i;
            Task fooWrappedInTask = Task.Run(
                async () =>
                    {
                        string res1 = null;
                        string ip = myIp.Remove(myIp.LastIndexOf('.'), myIp.Length - myIp.LastIndexOf('.'))
                                    + $".{j + 10}";
                        IPStatus t = await pingAsync($"{ip}");
                        lock (locker)
                        {
                            res1 += $"{ip} : {t.ToString()}\n";
                        }
                        return res1;
                    }).ContinueWith(act);
            taskList.Add(fooWrappedInTask);
        }
        Task.WaitAll(taskList.ToArray());
        return res;
    }
READ ALSO
Как активировать кнопку при выборе двух элементов ListView? WPF

Как активировать кнопку при выборе двух элементов ListView? WPF

Есть ListView и кнопка для сравнения двух элементов, которая должна быть активна, когда выбраны два элементаЕсть такой код XAML:

270
C# WPF Prism PopupWindowAction События окна

C# WPF Prism PopupWindowAction События окна

Хочу сделать свою "non client area" в popup окнеКак и где мне можно работать с code-behind PopupWindowAction окна? Можно ли реагировать на события PopupWindowAction окна...

184
Объясните код c#

Объясните код c#

Вот кодЧто делает, понять не могу

231
Ошибка PHP Fatal error: require(): Failed opening required на php7.0 yii2

Ошибка PHP Fatal error: require(): Failed opening required на php7.0 yii2

На хостинге работало все нормально,как только перенес на vps ошибкалоги тут -

214