Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
4 / 4 / 0
Регистрация: 19.08.2013
Сообщений: 138
1

Асинхронное программирование

28.04.2018, 18:29. Показов 1386. Ответов 3

Author24 — интернет-сервис помощи студентам
Здравствуйте. Написал класс для работа с API сайта, и он работает, что крайне странно, потому что в асинхронном программировании я пока ничего не понимаю. Но есть проблема: судя по тому, как долго выполняется программа, я сделал вывод, что новая итерация цикла в функции GetHashrate() начинается только после окончания предыдущей. То же самое и в цикле GetHashrate(int algo). Получается, программа последовательно отправляет 31*2=62 запроса к API сайта. Как можно это исправить, что бы программа сразу отправляла все запросы?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Threading.Tasks;
 
namespace AsincExample
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var h in Api.GetHashrate().GetAwaiter().GetResult())
                Console.WriteLine(h.Count.ToString());
        }
    }
    class Api
    {
        static string apiAdressMethod = "https://api.nicehash.com/api?method=orders.get";
        static int algorithmsQuantity = 31;
        public static async Task<List<Dictionary<float, float>>> GetHashrate()
        {
            List<Dictionary<float, float>> Hashrate = new List<Dictionary<float, float>>();
            for (byte algo = 0; algo < algorithmsQuantity; algo++)
                Hashrate.Add(await GetHashrate(algo));
            return Hashrate;
        }
        static async Task<Dictionary<float, float>> GetHashrate(int algo)
        {
            Dictionary<float, float> Hashrate = new Dictionary<float, float>();
            for (byte location = 0; location <= 1; location++)
                foreach (Order o in (await GetHashrate(location, algo)).Result.Order)
                {
                    float price = float.Parse(o.Price, CultureInfo.InvariantCulture);
                    float speed = float.Parse(o.AcceptedSpeed, CultureInfo.InvariantCulture);
                    if (o.Type == "0")
                    {
                        if (Hashrate.ContainsKey(price))
                            Hashrate[price] += speed;
                        else
                            Hashrate.Add(price, speed);
                    }
                }
            return Hashrate;
        }
        static async Task<Answer> GetHashrate(int location, int algo)
        {
            using (var http = new HttpClient())
            using (var stream = await http.GetStreamAsync(apiAdressMethod + $"&location={location}&algo={algo}"))
            {
                var serializer = new DataContractJsonSerializer(typeof(Answer));
                return (Answer)serializer.ReadObject(stream);
            }
        }
 
        [DataContract]
        class Answer
        {
            [DataMember(Name = "result")]
            public Result Result { get; set; }
            [DataMember(Name = "method")]
            public string Method { get; set; }
        }
        [DataContract]
        class Result
        {
            [DataMember(Name = "orders")]
            public Order[] Order { get; set; }
            [DataMember(Name = "timestamp")]
            public string Timestamp { get; set; }
        }
        [DataContract]
        class Order
        {
            [DataMember(Name = "limit_speed")]
            public string LimitSpeed { get; set; }
            [DataMember(Name = "alive")]
            public string Alive { get; set; }
            [DataMember(Name = "price")]
            public string Price { get; set; }
            [DataMember(Name = "id")]
            public string Id { get; set; }
            [DataMember(Name = "type")]
            public string Type { get; set; }
            [DataMember(Name = "workers")]
            public string Workers { get; set; }
            [DataMember(Name = "algo")]
            public string Algo { get; set; }
            [DataMember(Name = "accepted_speed")]
            public string AcceptedSpeed { get; set; }
        }
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.04.2018, 18:29
Ответы с готовыми решениями:

Асинхронное программирование await async
Всем привет! Пытаюсь разобраться с асинхронным вызовом методов. Узнал такую вещь: если...

Клиент-Серверное приложение, асинхронное программирование
Здравствуйте, это мой первый опыт в написании приложений такого плана, но я прочитал уже довольно...

Асинхронное программирование: почему в AsyncCallback не указать метод обратного вызова
Доброго времени суток ! Не могу понять вот эту строчку r.BeginGetResponse(new...

Асинхронное логирование
Доброго времени. Пишу небольшой метод, который забирает данные и записывает их в файл. Запрос...

3
1150 / 858 / 263
Регистрация: 30.04.2009
Сообщений: 3,598
29.04.2018, 19:28 2
Лучший ответ Сообщение было отмечено fingolfin_ как решение

Решение

Если не понимаете как работает async await, то лучше не используйте.
Для выполнения параллельно задач из списка используйте Parallel.For:

C#
1
2
3
4
5
6
7
            ConcurrentBag<Dictionary<float, float>> Hashrate = new ConcurrentBag<Dictionary<float, float>>();
            Parallel.For(0, algorithmsQuantity, (algo) =>
            {
                Hashrate.Add(GetHashrate(algo));
            });
 
            return Hashrate.ToList();
Советую также статью с подробным описанием TPL (Task Parallel Library) и не только https://rsdn.org/article/dotne... Part_3.xml

Добавлено через 3 минуты
Данные в результирующем списке будут неупорядочены по индексу algo, т.к. нет гарантии, что все задачи будут заканчиваться поочередно.
1
4 / 4 / 0
Регистрация: 19.08.2013
Сообщений: 138
30.04.2018, 15:45  [ТС] 3
Спасибо! Все работает!
Правильно я понимаю, что если написать так, получится уже отсортированный по algo список?
C#
1
2
3
4
5
6
var Hashrate = new ConcurrentBag<(int algo, Dictionary<float, float> orders)>();
Parallel.For(0, algorithmsQuantity, (algo) =>
{
    Hashrate.Add((algo, GetHashrate(algo)));
});
return Hashrate.OrderBy(tuple => tuple.algo).Select(tuple => tuple.orders).ToList();
0
263 / 224 / 108
Регистрация: 09.12.2015
Сообщений: 652
30.04.2018, 16:55 4
Цитата Сообщение от fingolfin_ Посмотреть сообщение
Правильно я понимаю, что если написать так, получится уже отсортированный по algo список?
Если нужен упорядоченный по индексу список, элементы которого создаются параллельно,
то его проще всего получить с помощью Parallel LINQ:
C#
1
2
return ParallelEnumerable.Range(0, algorithmsQuantity).AsOrdered()
   .Select(x => GetHashrate(x)).ToList();
2
30.04.2018, 16:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.04.2018, 16:55
Помогаю со студенческими работами здесь

Асинхронное выполнение
Здравствуйте имеется простой метод, который посылает запрос на сервер и получает ответ,...

Асинхронное выполнение сортировки
Помогите выполнить задание:Продемонстрируйте асинхронное выполнение, то есть не дожидаясь окончания...

Асинхронное клиент серверное приложение
Всем доброго времени суток, а так же спасибо всем кто загляну и не прошёл мимо. Сразу...

Как написать асинхронное лямбда-выражение?
Вопрос в заголовке.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru