Как вызвать асинхронную операцию как синхронизацию? - PullRequest
0 голосов
/ 12 ноября 2010

У меня есть сторонняя служба, у которой есть асинхронная операция DoAsync () и событие Done (). Как я могу создать свою собственную операцию синхронизации DoSync ()? Я хочу что-то вроде этого (в псевдокоде):

operation DoSync()
{
    DoAsync();
    wait until Done();
}

Ответы [ 2 ]

2 голосов
/ 12 ноября 2010
1 голос
/ 12 ноября 2010

Один из способов сделать это - временно добавить обработчик событий, а в этом обработчике установить какой-нибудь ожидаемый объект.Вот пример, который показывает технику с одним из асинхронных методов, предоставляемых WebClient

using System;
using System.Net;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            WebClient w = new WebClient();

            using (var waiter = new ManualResetEventSlim())
            {
                DownloadDataCompletedEventHandler h = (sender, e) =>
                {
                    if (e.Error != null)
                    {
                        Console.WriteLine(e.Error);
                    }
                    waiter.Set();
                };

                w.DownloadDataCompleted += h;
                try
                {
                    w.DownloadDataAsync(new Uri("http://www.interact-sw.co.uk/iangblog/"));
                    Console.WriteLine("Downloading");
                    waiter.Wait();
                    Console.WriteLine("Finished!");
                }
                finally
                {
                    w.DownloadDataCompleted -= h;
                }
            }
        }
    }
}

Вот упрощенная версия, которая упрощает просмотр базовой техники, но которая не беспокоит такие вещи, как ошибкаобработка или приведение в порядок после себя:

WebClient w = new WebClient();

using (var waiter = new ManualResetEventSlim())
{
    w.DownloadDataCompleted += delegate { waiter.Set(); };
    w.DownloadDataAsync(new Uri("http://www.interact-sw.co.uk/iangblog/"));
    Console.WriteLine("Downloading");
    waiter.Wait();
    Console.WriteLine("Finished!");
}

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

...