您的位置:首页 > 编程语言 > C#

C# 异步和委托学习

2016-03-13 20:36 357 查看
IAsyncResult是接口:

  IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来实现原同步方法的异步调用,如 FileStream 类提供了 BeginRead 和 EndRead 方法来从文件异步读取字节,它们是 Read 方法的异步版本

Begin 方法包含同步方法签名中的任何参数,此外还包含另外两个参数:一个AsyncCallback 委托和一个用户定义的状态对象。委托用来调用回调方法,状态对象是用来向回调方法传递状态信息。该方法返回一个实现 IAsyncResult 接口的对象

End 方法用于结束异步操作并返回结果,因此包含同步方法签名中的 ref 和 out 参数,返回值类型也与同步方法相同。该方法还包括一个 IAsyncResult 参数,用于获取异步操作是否完成的信息,当然在使用时就必须传入对应的 Begin 方法返回的对象实例

开始异步操作后如果要阻止应用程序,可以直接调用 End 方法,这会阻止应用程序直到异步操作完成后再继续执行。也可以使用 IAsyncResult 的 AsyncWaitHandle 属性,调用其中的WaitOne等方法来阻塞线程。这两种方法的区别不大,只是前者必须一直等待而后者可以设置等待超时

如果不阻止应用程序,则可以通过轮循 IAsyncResult 的 IsCompleted 状态来判断操作是否完成,或使用 AsyncCallback 委托来结束异步操作。AsyncCallback 委托包含一个 IAsyncResult 的签名,回调方法内部再调用 End 方法来获取操作执行结果

//C#异步编程模式IAsyncResult之IAsyncResult 接口
public interface IAsyncResult

{
object AsyncState { get; }
WaitHandle AsyncWaitHandle { get; }
bool CompletedSynchronously { get; }
bool IsCompleted { get; }
}


以上是IAsyncResult 接口的属性。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

namespace ConsoleTest
{
public delegate int AddHandler(int a, int b);
public class 加法类
{
public static int Add(int a, int b)
{
Console.WriteLine("开始计算:" + a + "+" + b);
Thread.Sleep(3000); //模拟该方法运行三秒
Console.WriteLine("计算完成!");
return a + b;
}
}

#region
public class 同步调用
{
static void Main()
{
Console.WriteLine("===== 同步调用 SyncInvokeTest =====");
AddHandler handler = new AddHandler(加法类.Add);
int result = handler.Invoke(1, 2);

Console.WriteLine("继续做别的事情。。。");

Console.WriteLine(result);
Console.ReadKey();
}
}
#endregion
}


/*运行结果:
===== 同步调用 SyncInvokeTest =====
开始计算:1+2
计算完成!
继续做别的事情。。。
3

*/

public delegate int AddHandler(int a, int b);
public class 加法类
{
public static int Add(int a, int b)
{
Console.WriteLine("开始计算:" + a + "+" + b);
Thread.Sleep(3000); //模拟该方法运行三秒
Console.WriteLine("计算完成!");
return a + b;
}
}

#region 异步调用
public class 异步调用
{
static void Main()
{
Console.WriteLine("===== 异步调用 AsyncInvokeTest =====");
AddHandler handler = new AddHandler(加法类.Add);

//IAsyncResult: 异步操作接口(interface)
//BeginInvoke: 委托(delegate)的一个异步方法的开始
IAsyncResult result = handler.BeginInvoke(1, 2, null, null);

//如果在2秒内完成计算
if (result.AsyncWaitHandle.WaitOne(2000, true))
{
Console.WriteLine(handler.EndInvoke(result));
Console.WriteLine(result);
}

Console.WriteLine("继续做别的事情。。。");

//异步操作返回
Console.WriteLine(handler.EndInvoke(result));
Console.ReadKey();
}


运行结果:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace ConsoleTest
{
public delegate int AddHandler(int a, int b);
public class 加法类
{
public static int Add(int a, int b)
{
Console.WriteLine("开始计算:" + a + "+" + b);
Thread.Sleep(3000); //模拟该方法运行三秒
Console.WriteLine("计算完成!");
return a + b;
}
}

public class TestFun
{
//模拟一个耗时计算
static int LongTimeMethod()
{
int result = 0;
//Thread. Sleep(3000);
for (int i = 0; i <= 100; i++)
{
result += i;
}
return result;
}

static void Main()
{

//这里用到的是.Net中定义好的委托来执行BeginInvoke
Func<int> longTimeAction = new Func<int>(LongTimeMethod);
IAsyncResult asynResult = longTimeAction.BeginInvoke(null, null);

////WaitOne
////这个对象有一个WaitOne方法,还能接受一个超时时间,它会等待这个超时时间指定的长度
//Func<int> longTimeAction1 = new Func<int>(LongTimeMethod);
//IAsyncResult asynResult1 = longTimeAction1.BeginInvoke(null, null);
////可以继续处理别的事情
//if (asynResult1.AsyncWaitHandle.WaitOne(10000, true))//判断是不是结果为true,只等你10s
//{
//    int result1 = longTimeAction1.EndInvoke(asynResult1);
//    Console.WriteLine(result1);
//}

//回调
Func<int> longTimeAction2 = new Func<int>(LongTimeMethod);
//这里使用了一个lambda表达式,省了不少力啊
IAsyncResult asynResult2 = longTimeAction.BeginInvoke((result) =>
{
int ret = longTimeAction.EndInvoke(result);
Console.WriteLine(ret);
}, null);

//轮询
while (!asynResult.IsCompleted)
{
//当不是true时,就执行这里的代码
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("计算还未完成,等待中....");
Console.ForegroundColor = ConsoleColor.Yellow;
for (int i = 1; i < 100; i++)
{
for (int j = i; j < 100; j++)
{
int a = i, b = j;
Console.WriteLine("{0}*{1}={2}", a, b, a * b);
}
}
Console.Clear();
}
int result1 = longTimeAction.EndInvoke(asynResult);//当是true时,就将结果返回显示
Console.WriteLine("计算的结果为:" + result1);
Console.ReadLine();
}
}

#region 直接调用
//public class 同步调用
//{
//    static void Main()
//    {
//        Console.WriteLine("===== 同步调用 SyncInvokeTest =====");
//        AddHandler handler = new AddHandler(加法类.Add);
//        int result = handler.Invoke(1, 2);

//        Console.WriteLine("继续做别的事情。。。");

//        Console.WriteLine(result);
//        Console.ReadKey();
//    }
//    /*运行结果:
//     ===== 同步调用 SyncInvokeTest =====
//     开始计算:1+2
//     计算完成!
//     继续做别的事情。。。
//     3       */
//}
#endregion
#region 异步调用
//public class 异步调用
//{
//    static void Main()
//    {
//        Console.WriteLine("===== 异步调用 AsyncInvokeTest =====");
//        AddHandler handler = new AddHandler(加法类.Add);

//        //IAsyncResult: 异步操作接口(interface)
//        //BeginInvoke: 委托(delegate)的一个异步方法的开始
//        IAsyncResult result = handler.BeginInvoke(1, 2, null, null);

//        //如果在2秒内完成计算
//        if (result.AsyncWaitHandle.WaitOne(2000, true))
//        {
//            Console.WriteLine(handler.EndInvoke(result));
//            Console.WriteLine(result);
//        }

//        Console.WriteLine("继续做别的事情。。。");

//        //异步操作返回
//        Console.WriteLine(handler.EndInvoke(result));
//        Console.ReadKey();
//    }
//    /*运行结果:
//     ===== 异步调用 AsyncInvokeTest =====
//     继续做别的事情。。。
//     开始计算:1+2
//     计算完成!
//     3       */
//}
//#endregion

//public class 异步回调
//{
//    static void Main()
//    {
//        Console.WriteLine("===== 异步回调 AsyncInvokeTest =====");
//        AddHandler handler = new AddHandler(加法类.Add);

//        //异步操作接口(注意BeginInvoke方法的不同!)
//        IAsyncResult result = handler.BeginInvoke(1, 2, new AsyncCallback(回调函数), "AsycState:OK");
//        //IAsyncResult result1 = handler.BeginInvoke(3, 4, new AsyncCallback(CallBackFuncation), "异步回掉完成");

//        Console.WriteLine("继续做别的事情。。。");
//        Console.ReadKey();
//    }

//    static void 回调函数(IAsyncResult result)
//    {
//        //result 是“加法类.Add()方法”的返回值
//        //AsyncResult 是IAsyncResult接口的一个实现类,引用空间:System.Runtime.Remoting.Messaging
//        //AsyncDelegate 属性可以强制转换为用户定义的委托的实际类。
//        AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
//        Console.WriteLine(handler.EndInvoke(result));
//        Console.WriteLine(result.AsyncState);
//    }
//    /*运行结果:
//    ===== 异步回调 AsyncInvokeTest =====
//    开始计算:1+2
//    继续做别的事情。。。
//    计算完成!
//    3
//    AsycState:OK
//             */

//    static void CallBackFuncation(IAsyncResult result)
//    {
//        Console.WriteLine("这里是回掉函数");
//        AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
//        Console.WriteLine(handler.EndInvoke(result));
//        Console.WriteLine(result.AsyncState);

//    }
//}
#endregion
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: