C#/ ASPP.NET异步线程执行

时间:2009-11-23 09:39:29

标签: c# asynchronous methods

我对执行以下操作有些怀疑:

public class Test
{
    delegate int TestDelegate(string parameter);

    static void Main()
    {
        TestDelegate d = new TestDelegate(PrintOut);

        d.BeginInvoke("Hello", new AsyncCallback(Callback), d);

        // Give the callback time to execute - otherwise the app
        // may terminate before it is called
        Thread.Sleep(1000);
        Console.ReadKey(true);
    }

    static int PrintOut(string parameter)
    {
        Console.WriteLine(parameter);
        return 5;
    }

    static void Callback(IAsyncResult ar)
    {
        TestDelegate d = (TestDelegate)ar.AsyncState;
        Console.WriteLine("Delegate returned {0}", d.EndInvoke(ar));
    }
}

1)TestDelegate已经指向一个方法(“PrintOut”)。为什么我们再次在d.BeginInvoke中传递另一个方法(“回调”)( “你好”,新的 AysncCallback(回调),d);。这是否意味着d.BeginInvoke平行执行“PrintOut”和“Callback”?。请你逐行解释究竟发生了什么?

2)通常,Aysnchronous执行意味着“线程”的执行是不可预测的    还是最快的执行?

3)TestDelegate d = (TestDelegate)ar.AsyncState;     “TestDelegate”d是委托。如何将其投射到归档或财产? (ar.AsyncState

4)你能给我一些实例吗?我需要在哪里使用这种异步执行?

4 个答案:

答案 0 :(得分:2)

PrintOut是将在线程池的线程上执行的函数,是您的委托所指向的函数。 CallbackPrintOut完成后将执行的函数,您必须在其中调用EndXXX方法,该方法将为您提供PrintOut执行的结果。这两个函数并行执行 。这是逐行的:

  1. 创建指向PrintOut方法的委托
  2. 从线程池中绘制一个线程(如果可用)并通过传递“Hello”作为参数在该线程上运行PrintOut方法。
  3. 同时主线程休眠1秒
  4. 一旦PrintOut方法完成执行,就会调用Callback方法。这是处理异步操作结果的地方。
  5. 就转换而言:AsyncState是一个对象,.NET中的委托也是一个对象,因此没有问题。

答案 1 :(得分:2)

1)TestDelegate已经指向一个方法(“PrintOut”)。为什么我们再次在d.BeginInvoke中传递另一个方法(“回调”)(“Hello”,新的AysncCallback(回调),d);.这是否意味着d.BeginInvoke平行执行“PrintOut”和“Callback”?。您能否逐行解释究竟发生了什么?

  • PrintOut和Callback不会在并行执行。 PrintOut完成并返回后将调用回调。

2)通常,Aysnchronous执行意味着“线程”的执行不可预测或执行速度最快?

  • 否。异步执行意味着执行不是同步的。也就是说,执行的时间和执行时间与启动异步操作的代码片段的时序无关。它与同步执行相反。使用同步操作,您可能希望在执行下一个语句之前完成执行。例如,直接调用另一个方法是同步操作,或者另一个例子是在远程服务上调用一个函数并在继续之前等待它返回。

3)TestDelegate d =(TestDelegate)ar.AsyncState; “TestDelegate”d是委托。如何将其投射到归档或财产? (ar.AsyncState)

  • 代表不属于某个领域或财产。演员是另一种方式。该字段或属性正在转换为TestDelegate。

4)你能给我一些实例吗?我需要在哪里使用这种异步执行?

  • 例如,如果您有一个显示报告的用户界面。报告可能需要从数据库中的数据生成,并且需要很长时间才能生成。您可能希望异步生成报告,以便用户界面可以继续运行。如果报告未异步生成,则用户界面可能会被冻结,用户可能认为程序已崩溃。

答案 2 :(得分:1)

1)执行Callback后运行时将调用PrintOut

2)是的,这是不可预测的。 BeginInvoke使代码在池中的线​​程上执行,因此真正的性能取决于许多参数,例如程序其他位置的线程使用。

3)代表是对象。因此,对它们的引用可以转换为对象和向后。如果IAsyncResult返回BeginInvoke,则AsyncState存储委托,以便进行正确的结果提取。

4)来自程序的片段在用户身份验证后打开旋转门并进行指示(两者都很耗时):

if(user.Id.HasValue)
{
    Action openDoor = turnstile.Open;
    Action<LedColor> indicate = led.SetColor;
    // starting async operations
    openDoor.BeginInvoke(openDoor.EndInvoke, null);
    indicate.BeginInvoke(LedColor.Green, indicate.EndInvoke, null);
    // main thread activity.
    MakeRecordToLog();
}

答案 3 :(得分:0)

1)在您的工作(PrintOut)完成后调用回调。您也可以传递一个空值。

2)Aysnchronous执行意味着您的代码运行在除应用程序主线程之外的另一个线程上。

3)ar.AsyncState设置为您在BeginInvoke方法的第3个参数中传递的值。

4)看看这个:http://shiman.wordpress.com/2008/09/10/c-net-delegates-asynchronous-invocation-begininvoke-method/