异步编程设计模式

4

我正在为CF.NET开发一个小型技术框架,我的问题是如何编写异步部分?我在MSDN上读了很多东西,但对我来说并不清楚。

所以,这里是代码:

public class A
{
    public IAsyncResult BeginExecute(AsyncCallback callback)
    {
        // What should I put here ?
    }

    public void EndExecute()
    {
        // What should I put here ?
    }

    public void Execute()
    {
        Thread.Sleep(1000 * 10);
    }
}

如果有人能帮我...

谢谢!


你想做什么?你的问题根本没有任何意义。 - Darin Dimitrov
我正在尝试异步执行Execute方法(这只是一个示例,在现实中我正在等待一个(Unix)shell脚本完成)。因此,我可以选择同步或异步启动我的shell脚本。 - Arnaud F.
4个回答

7
您可以使用委托(Delegate):
public class A
{
    public void Execute()
    {
        Thread.Sleep(1000 * 3);
    }
}

class Program
{
    static void Main()
    {
        var a = new A();
        Action del = (() => a.Execute());
        var result = del.BeginInvoke(state =>
        {
            ((Action)state.AsyncState).EndInvoke(state);
            Console.WriteLine("finished");
        }, del);
        Console.ReadLine();
    }
}

更新:
如评论部分所请求,这里提供一个示例实现:
public class A
{
    private Action _delegate;
    private AutoResetEvent _asyncActiveEvent;

    public IAsyncResult BeginExecute(AsyncCallback callback, object state)
    {
        _delegate = () => Execute();
        if (_asyncActiveEvent == null)
        {
            bool flag = false;
            try
            {
                Monitor.Enter(this, ref flag);
                if (_asyncActiveEvent == null)
                {
                    _asyncActiveEvent = new AutoResetEvent(true);
                }
            }
            finally
            {
                if (flag)
                {
                    Monitor.Exit(this);
                }
            }
        }
        _asyncActiveEvent.WaitOne();
        return _delegate.BeginInvoke(callback, state);
    }

    public void EndExecute(IAsyncResult result)
    {
        try
        {
            _delegate.EndInvoke(result);
        }
        finally
        {
            _delegate = null;
            _asyncActiveEvent.Set();
        }
    }

    private void Execute()
    {
        Thread.Sleep(1000 * 3);
    }
}

class Program
{
    static void Main()
    {
        A a = new A();
        a.BeginExecute(state =>
        {
            Console.WriteLine("finished");
            ((A)state.AsyncState).EndExecute(state);
        }, a);
        Console.ReadLine();
    }
}

好的,但是如果我们拿Stream类的例子来说,它有明确的Begin/End方法,我能在我的A类中也这样做吗? - Arnaud F.
这正是我想要的 :), 只是不理解你的AutoResetEvent部分 ;) - Arnaud F.

1

你不需要特别做什么,因为调用者应该异步地调用你的方法。

他定义了一个指向你方法的新委托,并使用 .net 异步地调用你的方法。


0
在BeginExecute中,您必须启动异步操作(可能在单独的线程中开始执行),并尽快返回。Execute必须在所有操作结束时调用AsyncCallback,以便使用异步操作的人意识到并获取结果。EndExecute必须停止先前启动的异步操作(可能会中断由BeginExecute启动的线程)。 没有更多细节,这是我能做的最好的翻译。

0
如果您想异步运行一段代码,应该使用BackgroundWorker。当然,除非您调用的代码不支持原生的异步操作,就像读/写方法或服务调用一样。
如果您想通知异步操作已完成,请使用委托或事件回调。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接