ManualResetEvent类用法小结

假设有一个程序中调用了三个异步方法,代码如下:

public class Test
{
    public void Todo(string message)
    {
        Console.WriteLine("{0} {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), message);
    }

    private Action<string> _todo = null;

    public Test()
    {
        _todo = Todo;
    }

    public IAsyncResult BeginTodo(string message, AsyncCallback callback, object state)
    {
        return _todo.BeginInvoke(message, callback, state);
    }

    public void EndTodo(IAsyncResult ar)
    {
        _todo.EndInvoke(ar);
    }
}

public class Program
{
    static void callback1(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);
    }

    static void callback2(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);
    }

    static void callback3(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);
    }

    static public void Main(string[] args)
    {
        Test test1 = new Test();
        test1.BeginTodo("test1", callback1, test1);

        Test test2 = new Test();
        test2.BeginTodo("test2", callback2, test2);

        Test test3 = new Test();
        test3.BeginTodo("test3", callback3, test3);

        Console.ReadKey();
    }
}

执行结果如下图所示:



也就是说,异步方法的执行顺序是不固定的,但有时我们希望它们能按顺序执行,修改代码如下:

public class Program
{
    static void callback1(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);

        Test test2 = new Test();
        test2.BeginTodo("test2", callback2, test2);
    }

    static void callback2(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);

        Test test3 = new Test();
        test3.BeginTodo("test3", callback3, test3);
    }

    static void callback3(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);
    }

    static public void Main(string[] args)
    {
        Test test1 = new Test();
        test1.BeginTodo("test1", callback1, test1);        

        Console.ReadKey();
    }
}

看着有没有感觉很乱?能不能让代码既像开始那样有条理,又能按顺序执行呢?ManualResetEvent类出场了:

public class Program
{
    static ManualResetEvent done1 = new ManualResetEvent(false);
    static ManualResetEvent done2 = new ManualResetEvent(false);
    static ManualResetEvent done3 = new ManualResetEvent(false);

    static void callback1(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);
        done1.Set();
    }

    static void callback2(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);
        done2.Set();
    }

    static void callback3(IAsyncResult ar)
    {
        Test test = (Test)ar.AsyncState;
        test.EndTodo(ar);
        done3.Set();
    }

    static public void Main(string[] args)
    {
        Test test1 = new Test();
        test1.BeginTodo("test1", callback1, test1);
        done1.WaitOne(); //阻塞当前线程,待Set后继续执行

        Test test2 = new Test();
        test2.BeginTodo("test2", callback2, test2);
        done2.WaitOne(); //阻塞当前线程,待Set后继续执行

        Test test3 = new Test();
        test3.BeginTodo("test3", callback3, test3);
        done3.WaitOne(); //阻塞当前线程,待Set后继续执行

        Console.ReadKey();
    }
}


评论: 0 | 引用: 0 | 查看次数: 3504
发表评论
登录后再发表评论!