【问题标题】:Asynchronous programming design pattern异步编程设计模式
【发布时间】:2011-06-10 17:07:48
【问题描述】:

我正在为 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);
    }
}

如果有人可以帮助我...

谢谢!

【问题讨论】:

  • 你想做什么?你的问题毫无意义。
  • 我正在尝试异步执行Execute 方法(这只是一个示例,实际上我正在等待(Unix)shellscript 完成。所以我可以选择是否同步启动我的shellscript .

标签: c# design-patterns asynchronous compact-framework


【解决方案1】:

您可以使用委托:

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();
    }
}

更新:

根据 cmets 部分的要求,这里有一个示例实现:

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 类做同样的事情吗?
  • 这正是我想要的:),只是不明白你的 AutoResetEvent 部分;)
【解决方案2】:

你不需要做任何特别的事情,因为调用者应该叫你异步方法,

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      如果你想异步运行一段代码,你应该使用BackgroundWorker。当然,除非您调用的代码本身不支持异步操作。就像读/写方法或服务调用一样。

      如果要通知异步操作已完成,请使用委托或事件回调。

      【讨论】:

        猜你喜欢
        • 2011-08-21
        • 2010-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 2011-04-24
        • 2016-06-20
        相关资源
        最近更新 更多