Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
6 / 6 / 0
Регистрация: 23.10.2015
Сообщений: 141
1

Асинхронные делегаты

21.03.2016, 19:55. Показов 1335. Ответов 12
Метки нет (Все метки)

Здравствуйте ! Подскажите пожалуйста, (программа рабочая ) для чего в методе
public bool Factorize строки :

C#
1
2
3
 if (m1 == 1) return false;
             
         else return true;
Они в методе ничего не делают и их запись выглядит как формальность, но и без них метод не работает ? Никак не могу понять их предназначение .


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
// Листинг 10.11. Асинхронные делегаты  Pavlovs_243
 using System;
 using System.Threading;
 using System.Runtime.Remoting.Messaging;
                                          // асинхронный делегат
 public delegate bool AsyncDelegate( int Num, out int m1, out int m2 );
 
                 // класс, выполняющий разложение числа на множители
 public class Factorizer
 {
    public bool Factorize( int Num, out int m1, out int m2 )
    {  
        m1 = 1; m2 = Num;
        for (int i = 2; i < Num; i++)       
            if (Num % i == 0) { m1 = i; m2 = Num / i; break; }         
       
 
         if (m1 == 1) return false;
             
         else return true;
        
    }
 }
 
                        // класс, получающий делегата и результаты
 public class PNum
 {
    private int Number;
    public PNum( int number ) {  Number = number;  }
 
   // [OneWayAttribute()]
                               // метод, получающий результаты
 
//       public void Res( IAsyncResult ar )
//       {
//          int m1, m2 ;
                              // получение делегата из AsyncResult 
//          AsyncDelegate ad = (AsyncDelegate)((AsyncResult)ar).AsyncDelegate;
 
                 // получение результатов выполнения метода Factorize 
//          ad.EndInvoke( out m1, out m2, ar );
                             //  вывод результатов
        
//          Console.WriteLine( "Первый способ : множители {0} : {1} {2}",
//                           Number, m1, m2 );
//        }
 }
 // демонстрационный класс 
 
 public class Simple
 {
               
 
          // используется ожидание окончания выполнения 
     public void Num2()
     {
         Factorizer f = new Factorizer();
         AsyncDelegate ad = new AsyncDelegate( f.Factorize );
 
         int Num = 650, tmp;    //  1000589023
 
              // создание экземпляра класса, который будет вызван 
              // после завершения работы метода Factorize
         PNum n = new PNum( Num );
 
             // задание делегата метода обратного вызова 
 //        AsyncCallback callback = new AsyncCallback( n.Res );
 
             // асинхронный вызов метода Factorize 
         IAsyncResult ar = ad.BeginInvoke(
                           Num, out tmp, out tmp, null, null );
                          // ожидание завершения
         ar.AsyncWaitHandle.WaitOne( 10000, false );
         if ( ar.IsCompleted )
         {
             int m1, m2;
                 // получение результатов выполнения метода Factorize 
             ad.EndInvoke( out m1, out m2, ar );
                                             // вывод результатов
             Console.WriteLine("Второй способ :  множители {0} : {1} {2}", Num, m1, m2);
         }
     }
 
     public static void Main( )
     {
         Simple s = new Simple();
        // s.Num1();
         s.Num2();
         Console.ReadKey();
     }
 }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.03.2016, 19:55
Ответы с готовыми решениями:

асинхронные делегаты
Добрый день. Вопрос мой об ассинронных делегатах. Я не могу никак понять EndInvoke() дожидается...

Асинхронные сокеты
Здравствуйте. Очень нужна ваша помощь. Вот callback функция которая передается в метод асинхронного...

Асинхронные операции
Console.WriteLine(&quot;Some code&quot;); using (var fs = new System.IO.FileStream(&quot;File.txt&quot;,...

Асинхронные операции на C#
Реализую обмен данными с устройством по USB-каналу (bulk передача) с использованием функций WinUSB...

__________________

Записывайтесь на профессиональные курсы С#-разработчиков‌
12
Модератор
Эксперт .NET
5304 / 4100 / 1183
Регистрация: 12.10.2013
Сообщений: 11,909
Записей в блоге: 2
21.03.2016, 21:36 2
Цитата Сообщение от Борис_20 Посмотреть сообщение
Они в методе ничего не делают и их запись выглядит как формальность
Это как ничего ничего не делают? Метод должен вернуть или true, или false. Вот по сравнению с 1 этой переменной и идет возврат из метода.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.03.2016, 00:06 3
Ну и секунду истины, асинхронных делегатов не существует. Это просто тип данных. Асинхронными они могут быть или не быть в зависимости от вызывающего кода.
0
6 / 6 / 0
Регистрация: 23.10.2015
Сообщений: 141
22.03.2016, 11:35  [ТС] 4
Psilon,
Строка 69 , асинхронный вызов метода Factorize . Не понятно как это асинхронный вызов ?
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.03.2016, 12:17 5
Борис_20, это значит асинхронный вызов Но делегат от этого не стал каким-то другим. То есть берем функцию и вызываем её не синхронно (дожидаясь результата), а асинхронно (начинаем вычисления и пока они происходят занимаемся другими делами).

Вы пришли к барной стойке и заказали пиво, официант пошел наливать. Делегат называется "НАЛИВ ПИВА". Если вы стоите у стойки и ждете, то это синхронный вызов. Если вы пошли пообщаться вон с теми симпатичными девочками в углу зала, поиграли в карты, вернулись и забрали своё пиво - то это был асинхронный вызов, вы занимались своими делами, пока происходило выполнение НАЛИВА ПИВА.

Сам делегат НАЛИВ ПИВА никак не меняется в этих двух случаях, вопрос только в том, ждете ВЫ ответа или нет.
0
6 / 6 / 0
Регистрация: 23.10.2015
Сообщений: 141
22.03.2016, 18:27  [ТС] 6
Psilon,

Спасибо ! Сложно в таком сориентироваться , т.к. новое, незнакомое.


Цитата Сообщение от Psilon Посмотреть сообщение
асинхронно (начинаем вычисления и пока они происходят занимаемся другими делами)

1 вопрос : Какими делами ???

2 вопрос : Непонятно что делает 73 строка ??? : ar.AsyncWaitHandle.WaitOne( 10000, false );


В 74 строке : if ( ar.IsCompleted ) , если я правильно понял проверяется завершил ли метод Factorize свою работу и если завершил, то происходит получение результатов выполнения метода Factorize и вывод результатов.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.03.2016, 20:50 7
Борис_20, понимаете, форматирование кода и закомментированные куски, а также общая его неэффективность (вопрос к павловской) не позволяют мне нормально его читать Тупо мозг фильтрует и не хочет этого. Поэтому я описываю в общих чертах, как оно в принципе работает и должно выглядеть. А что написано в данном конкретном случае я не смотрел.

Т.к. второй вопрос однострочный, то на него можно легко ответить: асинхронно ждем 10 секунд, то есть мы ждем окончание задачи, но не более 10 секунд, а затем продолжаем выполнение.
0
6 / 6 / 0
Регистрация: 23.10.2015
Сообщений: 141
23.03.2016, 13:23  [ТС] 8
Psilon,
Не совсем понимаю, приходится строить догадки. А догадки это ближе к области самодеятельности. Прошу поясните, пожалуйста !?


Цитата Сообщение от Psilon Посмотреть сообщение
асинхронно ждем 10 секунд, то есть мы ждем окончание задачи, но не более 10 секунд, а затем продолжаем выполнение
P.S. Про делегат НАЛИВ ПИВА
http://privet-rostov.ru/rus/17... ivana.html


Допустим дождались окончания задачи хватило 10 секунд , значит код опроса :

C#
1
2
3
4
5
6
7
8
 if ( ar.IsCompleted )
         {
             int m1, m2;
                 // получение результатов выполнения метода Factorize 
             ad.EndInvoke( out m1, out m2, ar );
                                             // вывод результатов
             Console.WriteLine("Второй способ :  множители {0} : {1} {2}", Num, m1, m2);
         }
не нужен получается ? Тогда как выводить результат после окончания задачи, допустим дождались окончания задачи хватило 10 секунд ?
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.03.2016, 14:11 9
Борис_20, я вам так скажу. Код, который вы привели (опять же проблема учебника) - полная старая фигня, которую трудно читать и понимать Уже во времена ХР (15 лет назад!) появился .Net 2.0, в котором есть EAP, ну а уж в наше время начиная с висты есть TAP - основанный на тасках. Вот как выглядит этот пример на новой платформе:
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
using System;
using System.Threading.Tasks;
 
namespace ConsoleApplication14
{
    public delegate bool AsyncDelegate(int Num, out int m1, out int m2);
 
    // класс, выполняющий разложение числа на множители
    public class Factorizer
    {
        public bool Factorize(int Num, out int m1, out int m2)
        {
            m1 = 1; m2 = Num;
            for (int i = 2; i < Num; i++)
                if (Num % i == 0) { m1 = i; m2 = Num / i; break; }
            return m1 != 1;
        }
    }
 
    class Program
    {
        static async Task DoWork()
        {
            int Num = 650, num1 = 0, num2 = 0;
            AsyncDelegate ad = new Factorizer().Factorize;
            var task = Task.Run(() => ad(Num, out num1, out num2));
            if (task == await Task.WhenAny(task, Task.Delay(10000)))
            {
                Console.WriteLine("Рассчеты выполнены, num1 = {0} num2 = {1}", num1, num2);
            }
            else
            {
                Console.WriteLine("Рассчеты заняли более 10 секунд");
            }
        }
 
        static void Main()
        {
            DoWork().GetAwaiter().GetResult();
        }
    }
}
Попробуйте понять его. Он намного проще, поэтому думаю тут будет не так много вопросов. Потому что код из вашего учебника, во-первых работает НАМНОГО медленнее, во-вторых написан так, что понять его невозможно. Авторам таких учебников нужно по голове давать .
Собственно замеры (по ссылке) показывают, что использование этого подхода заставляет код работать в 30 раз медленнее, чем в моем варианте

Единственная сложность может по-моему возникнуть в месте if (task == await Task.WhenAny(task, Task.Delay(10000))), но тут все просто: мы запускаем одновременно две задачи, одна просто ждет 10 секунд, а вторая делает вычисления. WhenAny хватает первую попавшуюся задачу, как только она выполнена. Таким образом если вычисления заканчиваются успешно, то WhenAny возвращает нашу задачу (вычисленную), ну и task == task, очевидно true. Если же нет, то он возвращает Task.Delay(10000), так как это не равно нашей задачи, то будет false, следовательно произошел таймаут.

Добавлено через 1 минуту
Но асинхронность в консоли понять трудно, потому что в ней не виден смысл в ней. Чтобы это понять, стоит попробовать сделать винформ-приложение, которое выполняет долгие вычисления (та же факторизация). В консоли разницы вы не почувствуете, а вот в винформе СРАЗУ поймете зачем всё это нужно

Добавлено через 1 минуту
Борис_20, а насчет пива - я неплохо разбираюсь в статистике, и прекрасно знаю, как её можно крутить в одну и другую сторону, чтобы получать противоположные результаты (вот например вот так). Это не значит, что результаты исследования неверны, но в общем случае "ученые доказали" без деталей эксперимента (выборка/квантили/доверительные вероятности и интервалы/автокорелляция/спектр....) отношусь весьма скептически.
0
6 / 6 / 0
Регистрация: 23.10.2015
Сообщений: 141
23.03.2016, 14:36  [ТС] 10
Psilon,

Спасибо !!! Буду думать.


0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.03.2016, 14:50 11
Цитата Сообщение от Борис_20 Посмотреть сообщение
Здравствуйте ! Подскажите пожалуйста, (программа рабочая ) для чего в методе
public bool Factorize строки :
Кстати касаемо вашего вопроса эти строки вообще не нужны, т.к. они просто показывают, является ли одно число единицей (то есть смогли ли произвести факторизацию) или нет. Имхо это не нужно, лучше кортеж вернуть. Тогда код получается намного более читабельным (и компилятор может проверить, что мы правильно используем всё:
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
using System;
using System.Threading.Tasks;
 
namespace ConsoleApplication14
{
    public delegate Tuple<int, int> AsyncDelegate(int num);
 
    // класс, выполняющий разложение числа на множители
    public class Factorizer
    {
        public Tuple<int, int> Factorize(int num)
        {
            int m1 = 1, m2 = num;
            for (int i = 2; i < num; i++)
                if (num%i == 0)
                {
                    m1 = i;
                    m2 = num/i;
                    break;
                }
            return new Tuple<int, int>(m1, m2);
        }
    }
 
    class Program
    {
        static async Task DoWork()
        {
            int Num = 650;
            AsyncDelegate ad = new Factorizer().Factorize;
            var task = Task.Run(() => ad(Num));
            if (task == await Task.WhenAny(task, Task.Delay(10000)))
            {
                Console.WriteLine("Рассчеты выполнены, num1 = {0} num2 = {1}", task.Result.Item1, task.Result.Item2);
            }
            else
            {
                Console.WriteLine("Рассчеты заняли более 10 секунд");
            }
        }
 
        static void Main()
        {
            DoWork().GetAwaiter().GetResult();
            Console.ReadKey();
        }
    }
}
В результате имеем понятный и читаемый код, входные параметры - входные, выходные - выходные, а не смешивается всё в одну кучу.
0
6 / 6 / 0
Регистрация: 23.10.2015
Сообщений: 141
31.03.2016, 20:03  [ТС] 12
Psilon,

Спасибо за пример ! Пробую понять программу, но :
1) Программа не работает ;
2) Отдельные строки вызывают неопределенность в понимании, например строка 27

static async Task DoWork()

и строка 32

if (task == await Task.WhenAny(task, Task.Delay(10000)))
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
31.03.2016, 21:53 13
Борис_20, во-первых я подробно расписал, что это значит 2 постами выше

Что касается не работает - извиняйте:
0
Миниатюры
Асинхронные делегаты  
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.03.2016, 21:53

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Асинхронные операции
Есть у меня источник с элементами (ObservableCollection), и специальные коллекции &quot;отображения&quot;,...

Асинхронные socket и Callback
Здраствуйте. Подскажите как сделать.. У меня есть асинхронная модель socket. public void...

Асинхронные методы в стиле Erlang
Уже не в первый раз встречаюсь с задачей и не знаю, как её реализовать согласно задумке. Задача...

Клиент + Сервер, асинхронные сокеты
Привет! Пишу клиент серверное приложение на основе асинхронных сокетов. Цель передача картинки....


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.