多线程编程模型APM 、EAM、TAP

C#7.0

1、异步编程模式APM

类似xxxBegin,xxxEnd 一对方法委托线程池执行

 Func<int> b = new Func<int>(() =>
            {
                return 10;
            });

            b.BeginInvoke(x =>
            {
                int r = b.EndInvoke(x);
            }, null);

其他例如FileStream.ReadBegin,ReadEnd等

fs.BeginRead(bytes, 0, bytes.Length, ar =>
{
    var r = fs.EndRead(ar);
Console.WriteLine(r);

}, null);

  

2、基于事件的编程模型(EAP)

类似xxxAsync 

 WebClient client = new WebClient();
            Uri uri = new Uri("http://www.baidu.com");
            client.DownloadDataCompleted += (sender, e) =>
            {
                byte[] bytes = e.Result;
            };
            client.DownloadDataAsync(new Uri("http://www.baidu.com"));

  

3、基于Task的编程模型(TAP)

APM和EAP都能包装成Task使用(微软推荐使用Task)

如下使用Task.Factory.FromAsync()包装APM为TAP

 Action a = new Action(() =>
            {
                Console.WriteLine("hello");
            });
           
            Task.Factory.FromAsync(a.BeginInvoke, a.EndInvoke, string.Empty);

  

 string path = Environment.CurrentDirectory + "/2.txt";

            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                byte[] bytes = new byte[fs.Length];
                Task<int> t = Task.Factory.FromAsync(fs.BeginRead, fs.EndRead, bytes, 0, bytes.Length, null);
                Console.WriteLine(t.Result);
            }

如下使用TaskCompletionSource包装EAP为TAP

public static Task<int> DoS()
        {
            TaskCompletionSource<int> taskCompletionSource = new TaskCompletionSource<int>();

            WebClient client = new WebClient();

            client.DownloadDataAsync(new Uri("http://www.baidu.com"));
            client.DownloadStringCompleted += (sender, e) =>
            {
                try
                {
                    taskCompletionSource.TrySetResult(e.Result.Length);
                }
                catch (Exception ex)
                {
                    taskCompletionSource.TrySetException(ex);
                }
            };

            client.DownloadDataAsync(new Uri("http://www.baidu.com"));
            return taskCompletionSource.Task;
        }

  以下方法内部也是使用TaskCompletionSource

Task<byte[]> Task = client.DownloadDataTaskAsync(uri);

  

 

posted @ 2019-10-11 22:33  vvf  阅读(441)  评论(0编辑  收藏  举报