網站首頁 編程語言 正文
在前一篇中,了解了Task的基本用法
如果一個方法返回Task,Task<T>,如何獲取Task的返回值,獲取值的過程會阻塞線程嗎?
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";
});
}
可見,Task的Result屬性可以獲取返回值,而且,獲取返回值的過程線程是被阻塞的。
是否可以不阻塞線程,又能拿到某個線程的返回值呢?ContinueWith方法在某個線程結束之后進行,但同時不會阻塞線程。
static void Main(string[] args)
{
DoWorkAsync().ContinueWith((pre) =>
{
Console.WriteLine(pre.Result);
});
Console.WriteLine("我會什么時候顯示");
Console.ReadKey();
}
但ContinueWith總會在某個線程結束之后進行,是否可以對ContinueWith的過程控制一下呢?
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來判斷一個線程是否完成。
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的狀態。
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 < stringArray.Result.Length;i++)
{
Console.WriteLine(stringArray.Result[i].Substring(0,100));
}
}
else if (task.Status == TaskStatus.Canceled) //如果被取消
{
Console.WriteLine("{0}這個任務被取消了",task.Id);
}
else //發生錯誤
{
Console.WriteLine("發生錯誤了~~");
foreach (var item in task.Exception.InnerExceptions)
{
Console.WriteLine(item.Message);
}
}
});
Console.ReadKey();
}
如果要控制Task的生命周期,可以考慮使用TaskCompletionSource<T>。
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;
}
}
以上,通過TaskCompletionSource<T>的SetResult給線程設置返回值,通過TaskCompletionSource<T>的.Task有獲取了線程。
另外,從.NET 4.5開始,Task的靜態方法FromResult,接收T類型,返回Task<T>。
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);
}
原文鏈接:https://www.cnblogs.com/darrenji/p/4436411.html
相關推薦
- 2022-04-04 uni-app 數據上拉加載更多功能
- 2022-12-10 Qt顯示QImage圖像在label上,并保持自適應大小問題_C 語言
- 2022-07-14 python輸出小數精度控制的方法_python
- 2022-06-11 Kubernetes集群環境初始化_云其它
- 2022-09-08 Pytorch中transforms.Resize()的簡單使用_python
- 2022-07-12 websocket+redis動態訂閱和動態取消訂閱的實現示例_Redis
- 2023-07-24 利用keyup事件實現input框輸入0-1之間的數字且最多只能保留2位小數
- 2023-03-28 python數組如何添加整行或整列_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支