[C#]异步委托使用小计

时间:2022-01-19 08:48:50

APM(=Asynchronous Programming Model(=异步编程模型))

使用 IAsyncResult 设计模式的异步操作是通过名为 Begin操作名称 和 End操作名称 的两个方法来实现的,这两个方法分别开始和结束异步操作 操作名称。  例如,FileStream 类提供 BeginRead 和 EndRead 方法来从文件异步读取字节。 这两个方法实现了 Read 方法的异步版本。 在调用 Begin操作名称 后,应用程序可以继续在调用线程上执行指令,同时异步操作在另一个线程上执行。  每次调用 Begin操作名称 时,应用程序还应调用 End操作名称 来获取操作的结果。 ——MSDN

[C#]异步委托使用小计

[C#]异步委托使用小计

BeginInvoke 方法启动异步调用。 该方法与您需要异步执行的方法具有相同的参数,还有另外两个可选参数。第一个参数是一个 AsyncCallback 委托,该委托引用在异步调用完成时要调用的方法。 第二个参数是一个用户定义的对象,该对象将信息传递到回调方法。BeginInvoke 立即返回,不等待异步调用完成。 BeginInvoke 返回一个 IAsyncResult,后者可用于监视异步调用的进度。

EndInvoke 方法检索异步调用的结果。 在调用 BeginInvoke 之后随时可以调用该方法。 如果异步调用尚未完成,则 EndInvoke 会一直阻止调用线程,直到异步调用完成。 EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 <Out>  ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

无论您使用何种方法,都要调用 EndInvoke 来完成异步调用

异步执行方法的最简单方式是通过调用委托的 BeginInvoke 方法来开始执行方法,在主线程上执行一些操作,然后调用委托的 EndInvoke 方法。 EndInvoke 可能会阻止调用线程,因为该方法直到异步调用完成后才返回。 这种方式非常适合执行文件或网络操作。因为 EndInvoke 可能会阻塞,所以不应从服务于用户界面的线程调用该方法。

——MSDN

1.普通示例

using System;
using System.Runtime.Remoting.Messaging;

namespace ConsoleApplication18
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string, string> _processTimeFunc = new Func<string, string>((string arg) =>
            {
                return string.Format("{0} {1}", arg, DateTime.Now);
            });
            _processTimeFunc.BeginInvoke("Beijing ", InvokeTimeFuncEnd, _processTimeFunc);//将委托作为参数传递
            _processTimeFunc.BeginInvoke("Shanghai ", InvokeTimeFuncEnd2, null);//参数为空
            Console.ReadLine();
        }
        private static void InvokeTimeFuncEnd2(IAsyncResult ar)
        {
            AsyncResult _asyncResult = (AsyncResult)ar;
            Func<string, string> _processTimeFunc = (Func<string, string>)_asyncResult.AsyncDelegate;//获取委托
            Console.WriteLine(_processTimeFunc.EndInvoke(ar));
        }
        private static void InvokeTimeFuncEnd(IAsyncResult ar)
        {
            Func<string, string> _processTimeFunc = (Func<string, string>)ar.AsyncState;
            Console.WriteLine(_processTimeFunc.EndInvoke(ar));
        }
    }
}

代码效果

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

[C#]异步委托使用小计

 

2.IsCompleted使用示例

using System;

namespace ConsoleApplication18
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string, string> _processTimeFunc = new Func<string, string>((string arg) =>
           {
               return string.Format("{0} {1}", arg, DateTime.Now);
           });
            IAsyncResult _result = _processTimeFunc.BeginInvoke("Beijing ", null, null);
            while (!_result.IsCompleted)
            {
                Console.Write(".....");
            }
            Console.WriteLine("\r\n" + _processTimeFunc.EndInvoke(_result));
            Console.ReadLine();
        }

    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

代码效果

[C#]异步委托使用小计

 

3.超时设置

using System;
using System.Threading;

namespace ConsoleApplication18
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string, string> _processTimeFunc = new Func<string, string>((string arg) =>
           {
               Thread.Sleep(6000);
               return string.Format("{0} {1}", arg, DateTime.Now);
           });
            IAsyncResult _result = _processTimeFunc.BeginInvoke("Beijing ", null, null);
            if (_result.AsyncWaitHandle.WaitOne(5000, true))
                Console.WriteLine("\r\n" + _processTimeFunc.EndInvoke(_result));
            else
                Console.WriteLine("执行超时...");
            Console.ReadLine();
        }

    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }代码效果

[C#]异步委托使用小计