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

Допустим, нам нужно загрузить из инета главную гугла и яндекса через сильверлайт. Просто подгрузить как данные.
При этом, яндекс должен грузиться после гугла.
Это можно сделать примерно так (просто поменял линки и имена..):
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
Асинхронность2Синхронность
    #37103562
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пост немного сломался, но думаю мысль ясна.
Кстати, данные яндекс с гуглом не отдадут из-за кроссдоменной политики доступа, но не в этом суть.

Нашел следующий пример и думаю это то, что надо:
http://www.csharp411.com/convert-between-synchronous-and-asynchronous/
...
Рейтинг: 0 / 0
Асинхронность2Синхронность
    #37103905
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получилось нечто следующее:
код
Код: 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
Асинхронность2Синхронность
    #37104081
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже, дело в том что 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
Асинхронность2Синхронность
    #37104463
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmatic,

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

Это было бы решением, но нужно вызывать одну функцию четко после другой. Т.е. например для
Код: plaintext
1.
2.
LoadYandex();
LoadGoogle();
вызывать LoadGoogle() только после того как отработает LoadYandex().
...
Рейтинг: 0 / 0
Асинхронность2Синхронность
    #37114591
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это полезно когда нужно сделать определенную цепочку действий, например, авторизоваться и только затем что-то делать.
Пробовал:
Код: 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
Асинхронность2Синхронность
    #37114762
Фотография уТКа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmatic,

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

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

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

Допустим, у нас есть задача - авторизоваться на сервере и получить данные.
Это делается как-то так:
Код: 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
Асинхронность2Синхронность
    #37115272
i
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
i
Гость
enigmaticКак написать это правильно и просто?
Копал в сторону размещения асинхронных операций в отдельных потоках, и думаю правильно копал.
Копал неправильно. Смотри Rx
...
Рейтинг: 0 / 0
Асинхронность2Синхронность
    #37115633
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
i,

Почему именно Rx? Почему это нельзя сделать с помощью простых сигналов?
Ведь работает же, если не нужно дожидаться событий.
...
Рейтинг: 0 / 0
Асинхронность2Синхронность
    #37116083
Фотография уТКа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Асинхронность2Синхронность
    #37116513
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
"все украдено до нас"

дейлайте синхронизацию на основе ManualResetEvent, который шарится, первый метод его стопает и в колбеке отпускает, второй ждет освобождения.
...
Рейтинг: 0 / 0
Асинхронность2Синхронность
    #37117117
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в .net 4.0 пришло счастье Task.ContinueWith
...
Рейтинг: 0 / 0
Асинхронность2Синхронность
    #37118624
i
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
i
Гость
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
Асинхронность2Синхронность
    #37120770
Фотография уТКа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
@автор:

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

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

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

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

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

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

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

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

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

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

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


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