Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Асинхронность2Синхронность / 25 сообщений из 27, страница 1 из 2
08.02.2011, 09:17
    #37103471
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
Здравствуйте.

Допустим, нам нужно загрузить из инета главную гугла и яндекса через сильверлайт. Просто подгрузить как данные.
При этом, яндекс должен грузиться после гугла.
Это можно сделать примерно так (просто поменял линки и имена..):
GoogleAndYandex
Код: plaintext
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.
        WebClient client = new WebClient();
        public MainPage() {
            InitializeComponent();

            Load ();
        }

        private void LoadGoogleAndYandex() {
            this.client.OpenReadCompleted += new OpenReadCompletedEventHandler(Google_loaded);
            this.client.OpenReadAsync(new Uri("http://google.ru", UriKind.Absolute));
        }

        void Google_loaded(object sender, OpenReadCompletedEventArgs e) {
            this.client.OpenReadCompleted -= Google_loaded;

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();

            this.client.OpenReadCompleted += new OpenReadCompletedEventHandler(Yandex_loaded);
            this.client.OpenReadAsync(new Uri("http://yandex.ru", UriKind.Absolute));
        }

        void Yandex_loaded(object sender, OpenReadCompletedEventArgs e) {
            this.client.OpenReadCompleted -= Yandex_loaded;

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();
        }

Т.е. подгружаем сначала гугл, потом в обработчике подгрузки гугла грузим яндекс.

Теперь допустим, что нам нужно грузить сначала яндекс, затем гугл и гугл должен быть подгружен после яндекса.
Это можно сделать так:
YandexAndGoogle
Код: plaintext
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.
WebClient client = new WebClient();
        public MainPage() {
            InitializeComponent();

            Load ();
        }

        private void LoadYandexAndGoogle() {
            this.client.OpenReadCompleted += new OpenReadCompletedEventHandler(Yandex_loaded);
            this.client.OpenReadAsync(new Uri("http://yandex.ru", UriKind.Absolute));
        }

        void Yandex_loaded(object sender, OpenReadCompletedEventArgs e) {
            this.client.OpenReadCompleted -= Yandex_loaded;

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();

            this.client.OpenReadCompleted += new OpenReadCompletedEventHandler(Google_loaded);
            this.client.OpenReadAsync(new Uri("http://google.ru", UriKind.Absolute));
        }

        void Google_loaded(object sender, OpenReadCompletedEventArgs e) {
            this.client.OpenReadCompleted -= Google_loaded;

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();
        }


А как написать код, чтобы можно было "расцепить" загрузку яндекса и гугла?
Т.е. чтобы можно было написать что-то вроде:
Код: plaintext
1.
2.
3.
4.
5.
LoadYandex();
LoadGoogle();
//или
LoadGoogle();
LoadYandex();



SL 4.0, VS 2010.
...
Рейтинг: 0 / 0
08.02.2011, 09:57
    #37103562
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
Пост немного сломался, но думаю мысль ясна.
Кстати, данные яндекс с гуглом не отдадут из-за кроссдоменной политики доступа, но не в этом суть.

Нашел следующий пример и думаю это то, что надо:
http://www.csharp411.com/convert-between-synchronous-and-asynchronous/
...
Рейтинг: 0 / 0
08.02.2011, 12:07
    #37103905
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
Получилось нечто следующее:
код
Код: plaintext
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.
    public partial class MainPage : UserControl {
        WebClient client = new WebClient();
        ManualResetEvent signal = new ManualResetEvent(false);
        public MainPage() {
            InitializeComponent();

            LoadGoogle();
            LoadYandex();
        }

        private void LoadGoogle() {
            var s_Timer = new Timer(LoadingBegin, "http://google.ru", 0, Timeout.Infinite);
            signal.WaitOne();
        }

        private void LoadYandex() {
            var s_Timer = new Timer(LoadingBegin, "http://yandex.ru", 0, Timeout.Infinite);
            signal.WaitOne();
        }

        void LoadingBegin(object source) {
            Uri uri = new Uri(source as string, UriKind.Absolute);
            this.client.OpenReadCompleted += new OpenReadCompletedEventHandler(LoadingEnd);
            this.client.OpenReadAsync(uri);
        }

        void LoadingEnd(object sender, OpenReadCompletedEventArgs e) {
            this.client.OpenReadCompleted -= LoadingEnd;

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();

            if (signal != null)
                signal.Set();
        }
    }

но оно не совсем работает, потому что LoadingEnd не срабатывает по событию OpenReadCompleted или не срабатывает само событие OpenReadCompleted.
...
Рейтинг: 0 / 0
08.02.2011, 13:08
    #37104081
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
Похоже, дело в том что WebClient объявлен в главном потоке, а обработчик LoadingEnd должен отработать в отдельном.

Вобщем, переводя с русского на русский:
Как написать код, который делает 2 асинхронных вызова, один за другим, так чтобы они не были связаны между собой?
Чтобы вместо:
Код: plaintext
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.
    public partial class MainPage : UserControl {
        WebClient client=new WebClient();
        ManualResetEvent signal = new ManualResetEvent(false);
        public MainPage() {
            InitializeComponent();
            
            LoadYandexAndGoogle();
        }

        private void LoadYandexAndGoogle() {
            this.client.OpenReadCompleted += new OpenReadCompletedEventHandler(Yandex_loaded);
            this.client.OpenReadAsync(new Uri("http://yandex.ru", UriKind.Absolute));
        }

        void Yandex_loaded(object sender, OpenReadCompletedEventArgs e) {
            this.client.OpenReadCompleted -= Yandex_loaded;

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();

            this.client.OpenReadCompleted += new OpenReadCompletedEventHandler(Google_loaded);
            this.client.OpenReadAsync(new Uri("http://google.ru", UriKind.Absolute));
        }

        void Google_loaded(object sender, OpenReadCompletedEventArgs e) {
            this.client.OpenReadCompleted -= Google_loaded;

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();
        }

    }

Можно было написать:
Код: plaintext
1.
2.
3.
4.
5.
LoadYandex();
LoadGoogle();
//или
LoadGoogle();
LoadYandex();
...
Рейтинг: 0 / 0
08.02.2011, 15:20
    #37104463
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
enigmatic,

а что мешает создать (и использовать) два WebClient-а?
...
Рейтинг: 0 / 0
09.02.2011, 12:46
    #37106431
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
LR,

Это было бы решением, но нужно вызывать одну функцию четко после другой. Т.е. например для
Код: plaintext
1.
2.
LoadYandex();
LoadGoogle();
вызывать LoadGoogle() только после того как отработает LoadYandex().
...
Рейтинг: 0 / 0
14.02.2011, 11:35
    #37114591
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
Это полезно когда нужно сделать определенную цепочку действий, например, авторизоваться и только затем что-то делать.
Пробовал:
Код: plaintext
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.
    public partial class MainPage : UserControl {
        ManualResetEvent signal = new ManualResetEvent(false);

        public MainPage() {
            InitializeComponent();

            LoadYandex();
            LoadGoogle();
        }

        private void LoadGoogle() {
            Thread thread = new Thread(LoadingBegin);
            thread.Start("http://google.ru");
            signal.WaitOne();
        }

        private void LoadYandex() {
            Thread thread = new Thread(LoadingBegin);
            thread.Start("http://yandex.ru");
            signal.WaitOne();
        }

        void LoadingBegin(object source) {
            WebClient client = new WebClient();
            Uri uri = new Uri(source as string, UriKind.Absolute);
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(LoadingEnd);
            client.OpenReadAsync(uri);
        }

        void LoadingEnd(object sender, OpenReadCompletedEventArgs e) {

            string data;
            if (e.Error == null) data = new StreamReader(e.Result).ReadToEnd();

            if (signal != null)
                signal.Set();
        }
    }
Работает, но не возвращается из LoadYandex();
...
Рейтинг: 0 / 0
14.02.2011, 12:48
    #37114762
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
enigmatic,

ерундой занимаетесь...

если так нужно, создайте класс обертку для вашего функционала, в котором будет пул потоков и собственно метод для открытия потока, как потоки отработали кидать событие, а вы в своем классе на него подпишитесь и поймаете его.
...
Рейтинг: 0 / 0
14.02.2011, 13:23
    #37114829
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
уТКа,

Хорошо, так и попробую сделать. Под пулом потоков понимается ThreadPool или какой-то свой, пользовательский пул?
...
Рейтинг: 0 / 0
14.02.2011, 13:30
    #37114855
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
И так как все равно уже написал, то вот более подробное описание темы.

Допустим, у нас есть задача - авторизоваться на сервере и получить данные.
Это делается как-то так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
void LoadData() {
webclient.uploadStringAsyncCompleted += new ... (Authorized);
webclient.uploadStringAsync(serverUri, authorizationData);
}

void Authorized(..., EventArgs e) {
webclient.openReadAsyncCompleted += new ... (DataLoaded);
webclient.openReadAsync(serverDataUri);
}

void DataLoaded(..., EventArgs e) {
var data = e.Result;
}
Допустим, дальше у нас появилась необходимость проверять, авторизованы ли мы на сервере.
Пусть для этого нам служит некоторый сервлет "authorizeCheck", возвращающий истину, если мы авторизованы, иначе ложь. Тогда получается:
Код: plaintext
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.
void LoadData() {
webclient.openReadAsyncCompleted += new ... (AuthorizeCheckCompleted);
webclient.openReadAsync(serverAuthorizeCheckUri);
}

void AuthorizeCheckCompleted(..., EventArgs e) {
var checkResult = e.Result;
if (checkResult == true) LoadDataWithoutAuthorize();
else AuthorizeThenLoadData();
}

void LoadDataWithoutAuthorize() {
webclient.openReadAsyncCompleted += new ... (DataLoaded);
webclient.openReadAsync(serverDataUri);
}

void DataLoaded(..., EventArgs e) {
var data = e.Result;
}

void AuthorizeThenLoadData() {
webclient.uploadStringAsyncCompleted += new ... (Authorized);
webclient.uploadStringAsync(serverUri, authorizationData);
}

void Authorized(..., EventArgs e) {
webclient.openReadAsyncCompleted += new ... (DataLoaded);
webclient.openReadAsync(serverDataUri);
}
Допустим, дальше у нас появляется необходимость загрузки ури сервера из файла, которая тоже является асинхронной операцией. Код еще более усложняется. Допустим, у нас может появиться необходимость добавлять/убирать еще какие-нибудь шаги.
Вопрос, как избежать этой лапши и написать нормальный код, вроде:
Код: plaintext
1.
2.
3.
LoadData() {
Authorize();
RetrieveData();
}
если нам нужно просто авторизоваться на сервере и получить данные и:
Код: plaintext
1.
2.
3.
LoadData() {
if (!AuthorizeCheck()) Authorize();
RetrieveData();
}
если нам нужно проверять авторизованы ли мы перед получением данных.

Как написать это правильно и просто?
Копал в сторону размещения асинхронных операций в отдельных потоках, и думаю правильно копал. Но пока получить то что хотелось не удалось.
Код писал в блокноте, опустив детали, оставив только главное.
...
Рейтинг: 0 / 0
14.02.2011, 15:47
    #37115272
i
i
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
enigmaticКак написать это правильно и просто?
Копал в сторону размещения асинхронных операций в отдельных потоках, и думаю правильно копал.
Копал неправильно. Смотри Rx
...
Рейтинг: 0 / 0
14.02.2011, 18:30
    #37115633
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
i,

Почему именно Rx? Почему это нельзя сделать с помощью простых сигналов?
Ведь работает же, если не нужно дожидаться событий.
...
Рейтинг: 0 / 0
15.02.2011, 01:25
    #37116083
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
enigmatic,

на самом деле решил поинтересоваться этой темой, и вот что выходит:
Асинхронность 2 Синхронность в Сильвере крайне сложно реализовать, в частности в работе с WCF

интересные ссылки которые удалось нарыть:
http://blogroll.pcmag.ru/go.php?nid=174593
http://www.gotdotnet.ru/blogs/jinek/9397/
http://www.gotdotnet.ru/blogs/diverofdark/8134/

http://blogs.msdn.com/b/rxteam/
http://channel9.msdn.com/blogs/j.van.gogh/writing-your-first-rx-application
http://stackoverflow.com/questions/3801505/using-rx-to-simplify-an-asynchronous-silverlight-web-service-request

Async CTP: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=18712f38-fcd2-4e9f-9028-8373dc5732b2
...
Рейтинг: 0 / 0
15.02.2011, 10:59
    #37116513
stimpi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
"все украдено до нас"

дейлайте синхронизацию на основе ManualResetEvent, который шарится, первый метод его стопает и в колбеке отпускает, второй ждет освобождения.
...
Рейтинг: 0 / 0
15.02.2011, 13:56
    #37117117
stimpi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
в .net 4.0 пришло счастье Task.ContinueWith
...
Рейтинг: 0 / 0
16.02.2011, 07:26
    #37118624
i
i
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
enigmaticLR,

Это было бы решением, но нужно вызывать одну функцию четко после другой. Т.е. например для
Код: plaintext
1.
2.
LoadYandex();
LoadGoogle();
вызывать LoadGoogle() только после того как отработает LoadYandex().

C Rx нужно будет написать 4 строчки
Код: plaintext
1.
2.
3.
4.
var r = from y in LoadYandex()
           from g in LoadGoogle()
           select new{ Y = y, G=g}
          r.SubscribeOnDispatcher().Subscribe(r=> {//обработчик результата}); 
Это был пример оператора Join. C помощью ForkJoin можно выполнить запросы параллельно, дождаться их завершения, а затем выполнить обработку результатов
...
Рейтинг: 0 / 0
16.02.2011, 18:17
    #37120770
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
@автор:

я нашел и написал приложение для Синхронного вызова Ассинхронных методов:
вот рабочий пример

по работе нужно было, делюсь :)
...
Рейтинг: 0 / 0
17.02.2011, 00:52
    #37121324
i
i
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
уТКа@автор:

я нашел и написал приложение для Синхронного вызова Ассинхронных методов:
вот рабочий пример

по работе нужно было, делюсь :)

Утка, не читай русскоязычных блогов и не повторяй глупости от туда
...
Рейтинг: 0 / 0
17.02.2011, 01:32
    #37121352
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
i,

по меньше симсонов смотрите :D

когда говорят "надо Синхронный вызов WCF из Silverlight" - это значит нАдо.

мне платят и ладно
...
Рейтинг: 0 / 0
17.02.2011, 09:32
    #37121534
i
i
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
Мда, тяжела и неказиста жизнь простого программиста. Плохо иметь дремучее начальство.
SubscribeOnDispatcher автоматичиски переводит результаты выполнения в UI поток
...
Рейтинг: 0 / 0
17.02.2011, 13:12
    #37122159
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
i,

накидайте пример, с удовольствием посмотрю.
...
Рейтинг: 0 / 0
17.02.2011, 14:53
    #37122512
i
i
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
я уже накидывал
...
Рейтинг: 0 / 0
17.02.2011, 20:33
    #37123278
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
i,

да нифига это не рабочий код.
...
Рейтинг: 0 / 0
17.02.2011, 22:25
    #37123408
i
i
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
Там только наметки. Покажи код, сделаю рабочий
...
Рейтинг: 0 / 0
17.02.2011, 22:30
    #37123415
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронность2Синхронность
i,

возьми мой проект выше и вставь туда свой код во вьюху.
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Асинхронность2Синхронность / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]