Re: Лавинообразная сложность асинхронных методов
От: Ромашка Украина  
Дата: 10.04.12 03:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть такая задача:


http://nicksnettravels.builttoroam.com/post/2011/04/22/Tidying-up-Windows-Phone-7-2b-WCF-Synchronous-Programming-Model.aspx

Ты это искал?


Всё, что нас не убивает, ещё горько об этом пожалеет.
Re[7]: Лавинообразная сложность асинхронных методов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.04.12 05:40
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, gandjustas, Вы писали:


G>>А чем Rx не помог? Он же нормально такое будет описывать


G>>
G>>from n in service.Fun()
G>>from _2 in Observable.If(n%2 == 0, service.Action2(), Observable.Empty<Unit>())
G>>from _3 in Observable.If(n%3 == 0, service.Action3(), Observable.Empty<Unit>())
G>>from _4 in Observable.If(n%4 == 0, service.Action4(), Observable.Empty<Unit>())
G>>select "Completed";
G>>


V>А если целиком воспроизвести с подпиской на события с сохранением семантики?


Для каждого метода надо что-то в этом роде написать:

Observable.Zip(
    Observable.FromEventPattern<Args>(obj, "EventName"), 
    Observable.Start(() => obj.Method(params),
    (evt, _) => selector(evt))
Re: Лавинообразная сложность асинхронных методов
От: TK Лес кывт.рф
Дата: 10.04.12 07:09
Оценка: +2
Здравствуйте, Аноним, Вы писали:

А>А теперь попробуем написать асинхронный вариант. Замечу, что потребность взята не с потолка -- при использовании Windows Phone нет возможности вызова веб-методов синхронно -- только асинхронный вариант. У меня получилось вот что:


А можно сделать и так:


var funTask = TaskFactory.FromAsync(service.BeginFun, service.EndFun, null);
var action1Task = funTask.ContinueWith(task => task.Result % 2 == 0 ? TaskFactory.FromAsync(service.BeginAction1, service.EndAction1, null) : task).Unwrap();
var action2Task = funTask.ContinueWith(task => task.Result % 4 == 0 ? TaskFactory.FromAsync(service.BeginAction2, service.EndAction2, null) : task).Unwrap();
var action3Task = funTask.ContinueWith(task => task.Result % 8 == 0 ? TaskFactory.FromAsync(service.BeginAction3, service.EndAction3, null) : task).Unwrap();
Task.WaitAll(action1Task, action2Task, action3Task);
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Лавинообразная сложность асинхронных методов
От: HowardLovekraft  
Дата: 10.04.12 07:35
Оценка:
Здравствуйте, TK, Вы писали:

TK>А можно сделать и так:

при использовании Windows Phone

Таски появились в SL 5. А в Windows Phone версия SL — 4, разве не так?
Re[3]: yield return вместо async/await
От: Mr.Delphist  
Дата: 10.04.12 07:46
Оценка: +5 -1 :))) :)
Здравствуйте, Аноним, Вы писали:

А>Проклял 10 раз Микрософта за то что лишили возможности использовать синхронные методы. Сколько раз говорили: никогда не считайте себя умнее пользователя. Они подумали, что мы будем забывать выносить вызов методов из UI потока и вообще лишили нас возможности вызывать методы в UI потоке. Умные. Но вот что делать в таком случае -- они не подумали...


Безумно рад, что они так сделали. Орды индусов лишены возможности косячить хотя бы одним из возможных путей косячения. Как я ненавидел эти автостартующие жирные приложения в старых виндах — вздохнул с облегчением после Win7 (там система автоматически понижает приоритет потока, обслуживающего автостартующие приложения при входе в систему). Асинхронность — ещё один шаг в верном направлении. Кто не сумеет освоить state machine — будет обречен
Re[3]: Лавинообразная сложность асинхронных методов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.04.12 08:43
Оценка: 3 (1)
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, TK, Вы писали:


TK>>А можно сделать и так:

HL>

HL>при использовании Windows Phone

HL>Таски появились в SL 5. А в Windows Phone версия SL — 4, разве не так?

В WP7 версия SL не совпадает с десктопными.
Re[2]: Лавинообразная сложность асинхронных методов
От: Аноним  
Дата: 10.04.12 08:51
Оценка:
Здравствуйте, Ромашка, Вы писали:

Р>http://nicksnettravels.builttoroam.com/post/2011/04/22/Tidying-up-Windows-Phone-7-2b-WCF-Synchronous-Programming-Model.aspx


Р>Ты это искал?


Это было первой мыслью. Не работает в версии 7.1 -- просто зависает.
Re[4]: yield return вместо async/await
От: Аноним  
Дата: 10.04.12 09:05
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Безумно рад, что они так сделали. Орды индусов лишены возможности косячить хотя бы одним из возможных путей косячения.


Наивный вы человек. Индусов это меньше всего будет заботить -- они будут писать макароны как в самом первом посте и задумываться ни о чем не будут Это добавило геморрой только правильным людям, для которых писать лапша-код недопустимо (ранее был бы только один асинхронный вызов, теперь множество без надобности -- просто усложнение на ровном месте).

MD>Асинхронность — ещё один шаг в верном направлении.


В данном случае нужен лишь один асинхронный вызов с целью избежать длительной операции в UI-потоке. Запуск каждого метода в отдельном потоке ничего кроме сложности не привносит.

Но таким как вы это очень сложно увидеть. Вам MS будет сцать на голову -- а вы будете говорить "Божия роса".

MD>Кто не сумеет освоить state machine — будет обречен


Нифига -- индус просто будет писать спагетти с чувством выполненного долга. Даже не задумываясь, как говориться.

А зависания формы в WP7 очень легко достичь, работая с локальной базой данных. Так что только усложнили жизнь -- никакого профита абсолютно.

Ну и главное. С таким презрительным отношением к партнерам разработчикам далеко не уедешь. Единственные кто с ними будут работать -- так это те же индусы и будут писать так, что волосы на голове дыбом встанут.
Re[4]: Лавинообразная сложность асинхронных методов
От: HowardLovekraft  
Дата: 10.04.12 09:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>В WP7 версия SL не совпадает с десктопными.

Забавно. А как тогда, глядя на страничку с описанием в MSDN, понять, поддерживается ли возможность в Windows Phone?
Re[5]: Лавинообразная сложность асинхронных методов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.04.12 09:54
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, gandjustas, Вы писали:


G>>В WP7 версия SL не совпадает с десктопными.

HL>Забавно. А как тогда, глядя на страничку с описанием в MSDN, понять, поддерживается ли возможность в Windows Phone?

По Windows Phone отдельный reference
Re[5]: Лавинообразная сложность асинхронных методов
От: hardcase Пират http://nemerle.org
Дата: 10.04.12 09:54
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, gandjustas, Вы писали:


G>>В WP7 версия SL не совпадает с десктопными.

HL>Забавно. А как тогда, глядя на страничку с описанием в MSDN, понять, поддерживается ли возможность в Windows Phone?

Ыконка специальная есть там.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[8]: Лавинообразная сложность асинхронных методов
От: vdimas Россия  
Дата: 10.04.12 10:49
Оценка: -1
Здравствуйте, gandjustas, Вы писали:

V>>А если целиком воспроизвести с подпиской на события с сохранением семантики?


G>Для каждого метода надо что-то в этом роде написать:


G>
G>Observable.Zip(
G>    Observable.FromEventPattern<Args>(obj, "EventName"), 
G>    Observable.Start(() => obj.Method(params),
G>    (evt, _) => selector(evt))
G>


О том и речь... Не катит. Т.е. через обычную декомпозицию и кода не больше и статически проверяемо: http://www.rsdn.ru/forum/dotnet/4695456.1.aspx
Автор: vdimas
Дата: 10.04.12
Re[2]: Лавинообразная сложность асинхронных методов
От: Аноним  
Дата: 10.04.12 11:08
Оценка:
Здравствуйте, vdimas, Вы писали:

V>вроде идут повторы, начиная с конца.

V>А если вынести повторы в отдельные ф=ии?

Только нужно чуть исправить:


static MyDelegate MakeAction2(Sevice sevice, int n) {
  return (o, eventArgs1) => {
    if (n % 2 == 0) {
      service.Action3Completed += MakeAction3(service, n);
      service.StartAction2();
    }
////////////// Добавилось ////////////////
    else
       MakeAction3(service, n);
//////////////////////////////
  }
}



и так в каждом...

Это примерно то же самое, о чем я говорил тут http://rsdn.ru/forum/dotnet/4695359.aspx?tree=tree
Автор:
Дата: 10.04.12
(вариант 2).
Re[9]: Лавинообразная сложность асинхронных методов
От: Аноним  
Дата: 10.04.12 11:19
Оценка:
Здравствуйте, vdimas, Вы писали:

G>>
G>>Observable.Zip(
G>>    Observable.FromEventPattern<Args>(obj, "EventName"), 
G>>    Observable.Start(() => obj.Method(params),
G>>    (evt, _) => selector(evt))
G>>


V>О том и речь... Не катит. Т.е. через обычную декомпозицию и кода не больше и статически проверяемо: http://www.rsdn.ru/forum/dotnet/4695456.1.aspx
Автор: vdimas
Дата: 10.04.12


Можно сделать статически проверяемое (есть метод FromEventPattern без рефлекшена). Но, как вы справедливо заметили -- ничем не лучше предложенного мной варианта №2 здесь http://rsdn.ru/forum/dotnet/4695359.aspx?tree=tree
Автор:
Дата: 10.04.12


То есть смысл один: если нужно вызывать -- вызываем метод а по завершению событие Complete, если не нужно вызывать -- просто дергаем событие Complete.

Хотя, возможно, с Rx в таком виде чуть компактнее будет запись. Но с учетом того, что нужно проверить ошибки и восстановить сессию -- вероятно придется выносить логику проверки в отдельный метод -- тогда компактность будет практически идентичной.
Re[3]: Лавинообразная сложность асинхронных методов
От: vdimas Россия  
Дата: 10.04.12 11:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Только нужно чуть исправить:

А>и так в каждом...

Не нужно. Этот else уже есть на самом верхнем уровне.
Re[9]: Лавинообразная сложность асинхронных методов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.04.12 11:35
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, gandjustas, Вы писали:


V>>>А если целиком воспроизвести с подпиской на события с сохранением семантики?


G>>Для каждого метода надо что-то в этом роде написать:


G>>
G>>Observable.Zip(
G>>    Observable.FromEventPattern<Args>(obj, "EventName"), 
G>>    Observable.Start(() => obj.Method(params),
G>>    (evt, _) => selector(evt))
G>>


V>О том и речь... Не катит.

Ты о чем?

V>Т.е. через обычную декомпозицию и кода не больше и статически проверяемо: http://www.rsdn.ru/forum/dotnet/4695456.1.aspx
Автор: vdimas
Дата: 10.04.12

Только тебе придется такой код писать для каждой последовательности, потому что у тебя проверки внутри коллбеков. А Observable обертка может быть тупо сгенерирована один раз.
Что касается статически проверяемого кода, то у метода FromEventPattern есть перегрузки, где не требуется строковая передача имени.
Re[4]: Лавинообразная сложность асинхронных методов
От: Аноним  
Дата: 10.04.12 11:39
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Не нужно. Этот else уже есть на самом верхнем уровне.


Где на самом верхнем уровне?

Вот это:

service.FunCompleted += (sender, eventArgs) => { 
  int n = eventArgs.Argument;

  if (0 == n%2)
    MakeAction2(service, n)(sender, eventArgs); 
  else if (0 == n%3)
    MakeAction3(service, n)(sender, eventArgs); 
  else if (0 == n%4)
    MakeAction4(service, n)(sender, eventArgs);
}


Представьте ситуацию:

Action2 -- должно выполняться.
Action3 -- НЕ должно выполняться (пропускаем).
Action4 -- должно выполняться.

Ваш вариант выполнит Action2, попадет в MakeAction3 и на этом завершиться. А нужно еще выполнить MakeAction4...
Re[5]: Лавинообразная сложность асинхронных методов
От: vdimas Россия  
Дата: 10.04.12 12:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ваш вариант выполнит Action2, попадет в MakeAction3 и на этом завершиться. А нужно еще выполнить MakeAction4...


Тогда вроде более точно будет так:
static MyDelegate MakeAction2(Sevice sevice, int n) {
  if (n % 2 == 0)
    return (o, eventArgs1) => {
      service.Action2Completed += MakeAction3(service, n);
      service.StartAction2();
    }
  else
    return MakeAction3(service, n);
}

// и на верхнем уровне совсем просто:
var service = new Service();
service.FunCompleted += (sender, eventArgs) => { MakeAction2(service, eventArgs.Argument)(sender, eventArgs); };
service.StartFun();
Re[10]: Лавинообразная сложность асинхронных методов
От: vdimas Россия  
Дата: 10.04.12 12:31
Оценка:
Здравствуйте, gandjustas, Вы писали:


V>>О том и речь... Не катит.

G>Ты о чем?

Нетипизировано (согласен, возразили), но размер кода будет в итоге такой же, как в некоторых приведенных декомпозициях, например последний вариант здесь: http://www.rsdn.ru/forum/dotnet/4696155.1.aspx
Автор: vdimas
Дата: 10.04.12

Т.е. смысла нет.

G>Только тебе придется такой код писать для каждой последовательности, потому что у тебя проверки внутри коллбеков. А Observable обертка может быть тупо сгенерирована один раз.


Покажи каким образом, если каждый раз вызываются разные методы и подписка идет к разным событиям?

Одно из возможных решений, которое я бы предложил, если бы речь не шла о ветвлении всего на 3 ветки — это сделать адаптеры для получения одинакового интерфейса под все разные методы и калбэки: { предикат, ф-ия, сигнал }. После этого будет миниатюрный код для запуска этого дела на чем угодно и как угодно даже вручную: в параллель либо последовательно.
Re: Лавинообразная сложность асинхронных методов
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.04.12 12:45
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>И, собственно, вопрос. Что делать, если таких вот Action в проекте действительно много? Как быть, как написать? Это ж идиотизм какой-то.


Адъ и ужос!

Заведите массив ссылок на эти самые action. Заполняйте его после возврата из Fun(), а потом после возврата из каждой очередной ActionN() берите из массива следующий элемент, пока не кончатся.

Немного обобщая, при асинхронном программировании лучше состояние держать в явном виде, а не размазывать тонким слоем по логике. И иметь где-то централизованный код, который, глядя на текущее состояние и очередное событие, принимает решение, какое действие сделать следующим, и как изменить состояние.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.