Events 如何以同步方式调用异步操作?

Events 如何以同步方式调用异步操作?,events,asynchronous,c#-4.0,Events,Asynchronous,C# 4.0,我有一个第三方服务,它具有异步DoAsync()操作和Done()事件。如何创建自己的sync DoSync()操作? 我想要这样的smth(伪代码): 一种方法是临时添加一个事件处理程序,并在该处理程序中设置某种类型的可等待对象。下面是一个示例,展示了使用WebClient using System; using System.Net; using System.Threading; namespace ConsoleApplication1 { class Program

我有一个第三方服务,它具有异步DoAsync()操作和Done()事件。如何创建自己的sync DoSync()操作? 我想要这样的smth(伪代码):


一种方法是临时添加一个事件处理程序,并在该处理程序中设置某种类型的可等待对象。下面是一个示例,展示了使用
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!");
}

在大多数情况下,您需要确保检测到错误,并在完成时分离处理程序-我只是提供了较短的版本来帮助说明这一点。实际上,我不会在实际程序中使用简化的事件处理程序。

一种方法是临时添加一个事件处理程序,并在该处理程序中设置某种可等待的对象。下面是一个示例,展示了使用
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!");
}
在大多数情况下,您需要确保检测到错误,并在完成时分离处理程序-我只是提供了较短的版本来帮助说明这一点。我不会在真正的程序中实际使用这个简化的程序。

尝试AutoResetEvent

尝试AutoResetEvent