.Net中Task Parallel Library的进阶用法

前一篇中,了解了Task的基本用法

如果一个方法返回Task,Task,如何获取Task的返回值,获取值的过程会阻塞线程吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static void Main(string[] args)
{
    var result = DoWorkAsync().Result;
    Console.WriteLine(result);
    Console.WriteLine("我会什么时候显示");
    Console.ReadKey();
}
static Task<string> DoWorkAsync()
{
    return Task<string>.Factory.StartNew(() =>
    {
        Thread.Sleep(3000);
        return "hello";
    });
}</string></string>

可见,Task的Result属性可以获取返回值,而且,获取返回值的过程线程是被阻塞的。

是否可以不阻塞线程,又能拿到某个线程的返回值呢?ContinueWith方法在某个线程结束之后进行,但同时不会阻塞线程。

1
2
3
4
5
6
7
8
9
static void Main(string[] args)
{
    DoWorkAsync().ContinueWith((pre) =>
    {
        Console.WriteLine(pre.Result);
    });
    Console.WriteLine("我会什么时候显示");
    Console.ReadKey();
}

但ContinueWith总会在某个线程结束之后进行,是否可以对ContinueWith的过程控制一下呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
static void Main(string[] args)
{
    DoWorkAsync().ContinueWith((pre) =>
    {
        Console.WriteLine(pre.Result);
    }, TaskContinuationOptions.NotOnFaulted);
    DoWorkAsync().ContinueWith((pre) =>
    {
        Console.WriteLine(pre.Exception);
    },TaskContinuationOptions.OnlyOnFaulted);
    Console.WriteLine("我会什么时候显示");
    Console.ReadKey();
}

以上,当没有错误的时候就把返回值显示出来,有错误就把错误信息显示出来。

还可以通过Task的实例方法IsCompleted来判断一个线程是否完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static void Main(string[] args)
{
    var doWorkTask = DoWorkAsync();
    if (doWorkTask.IsCompleted)
    {
        Console.WriteLine(doWorkTask.Result);
    }
    else
    {
        doWorkTask.ContinueWith((pre) =>
        {
            Console.WriteLine(pre.Result);
        }, TaskContinuationOptions.NotOnFaulted);
        doWorkTask.ContinueWith((pre) =>
        {
            Console.WriteLine(pre.Exception);
        }, TaskContinuationOptions.OnlyOnFaulted);
    }
     
    Console.WriteLine("我会什么时候显示");
    Console.ReadKey();
}

Task的Status属性,以及结合TaskStatus枚举,可以判断Task的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static void Main(string[] args)
{
    var httpClient = new HttpClient();
    Task<string> baiduTask = httpClient.GetStringAsync("http://www.baidu.com");
    var httpClient2 = new HttpClient();
    Task<string> sinaTask = httpClient2.GetStringAsync("http://www.sina.com.cn");
    //等上面2个任务完成时这里再开始
    Task<string> task = Task.WhenAll(baiduTask, sinaTask);
    task.ContinueWith(stringArray =>
    {
        //如果任务完成
        if (task.Status == TaskStatus.RanToCompletion)
        {
            for (int i = 0; i </string></string></string>

如果要控制Task的生命周期,可以考虑使用TaskCompletionSource

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
   static void Main(string[] args)
    {
        AsyncFactory.GetIntAsync().ContinueWith((prev) =>
        {
            if (prev.Status == TaskStatus.RanToCompletion)
            {
                Console.WriteLine(prev.Result);
            }
            else if (prev.Status == TaskStatus.Canceled)
            {
                Console.WriteLine("任务被取消");
            }
            else
            {
                Console.WriteLine("发生错误哦");
                Console.WriteLine(prev.Exception);
            }
        });
        Console.ReadKey();
    }
}
public static class AsyncFactory
{
    public static Task<int> GetIntAsync()
    {
        var tsc = new TaskCompletionSource<int>();
        var timer = new System.Timers.Timer(2000);
        timer.AutoReset = false;
        timer.Elapsed += (s, e) =>
        {
            tsc.SetResult(10);
            timer.Dispose();
        };
        timer.Start();
        return tsc.Task;                    
    }
}</int></int>

以上,通过TaskCompletionSource的SetResult给线程设置返回值,通过TaskCompletionSource的.Task有获取了线程。

另外,从.NET 4.5开始,Task的静态方法FromResult,接收T类型,返回Task

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static void Main(string[] args)
{
    var intTask = GetIntAsync();
    if (intTask.Status == TaskStatus.RanToCompletion)
    {
        Console.WriteLine(intTask.Result);
    }
    else if (intTask.Status == TaskStatus.Canceled)
    {
        Console.WriteLine("任务被取消");
    }
    else
    {
        Console.WriteLine("发生错误哦");
        Console.WriteLine(intTask.Exception);
    }
    Console.ReadKey();
}
static Task<int> GetIntAsync()
{
    return Task.FromResult(10);
}</int>

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对IT俱乐部的支持。如果你想了解更多相关内容请查看下面相关链接

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/code/asp-net/1266.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部