【问题标题】:C# /ASP.NET Asynchronous Thread ExecutionC# /ASP.NET 异步线程执行
【发布时间】:2009-11-23 17:59:16
【问题描述】:

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

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( "Hello",new AysncCallback(Callback),d);。这是否意味着 d.BeginInvoke 并行执行“PrintOut”和“Callback”?你能逐行解释到底发生了什么吗?

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

3) TestDelegate d = (TestDelegate)ar.AsyncState; “TestDelegate” d 是一个委托。如何将其转换为归档或财产? (ar.AsyncState)

4) 能否提供一些现场示例,我需要在哪里使用此异步执行?

【问题讨论】:

    标签: c# asynchronous methods


    【解决方案1】:

    1)TestDelegate 已经指向一个方法(“PrintOut”)。为什么我们再次在 d.BeginInvoke("Hello",new AysncCallback(Callback),d); 中传递另一个方法(“callback”)。这是否意味着 d.BeginInvoke 并行执行“PrintOut”和“Callback”?请您逐行解释到底发生了什么?

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

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

    • 没有。异步执行意味着执行不是同步的。即..执行的时机和执行时间与启动异步操作的那段代码的时机无关。它与同步执行相反。使用同步操作,您会期望在执行下一条语句之前完成执行。比如直接调用另一个方法是同步操作,或者另一个例子是调用远程服务上的一个函数,等待它返回再继续。

    3) TestDelegate d = (TestDelegate)ar.AsyncState; “TestDelegate” d 是一个委托。如何将其转换为归档或财产? (ar.AsyncState)

    • 委托不是字段或属性的大小写。演员阵容则相反。正在将字段或属性转换为 TestDelegate。

    4) 能否提供一些现场示例,我需要在哪里使用此异步执行?

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

    【讨论】:

      【解决方案2】:

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

      1. 创建一个指向 PrintOut 方法的委托
      2. 从线程池中绘制一个线程(如果可用)并通过传递“Hello”作为参数在该线程上运行 PrintOut 方法。
      3. 同时主线程休眠 1 秒
      4. 一旦 PrintOut 方法执行完毕,就会调用 Callback 方法。这是您处理异步操作结果的地方。

      就转换而言:AsyncState 是一个对象,.NET 中的委托也是一个对象,所以转换没有问题。

      【讨论】:

        【解决方案3】:

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

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

        3) 代表是对象。因此,对它们的引用可以转换为对象并向后转换。如果BeginInvoke 返回IAsyncResultAsyncState 存储委托,以使正确的结果提取成为可能。

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

        【讨论】:

          【解决方案4】:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-22
            • 2020-01-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多