Task.ContinuteWith()未按预期执行
本文关键字:执行 ContinuteWith Task | 更新日期: 2023-09-27 18:19:30
我试图使用async/await重写我的一些旧代码,并使用ContinueWith()链接任务,并使用TaskContinuationOptions.NotOnFaulted.检查异常
当我调试代码时,我注意到它并没有像我预期的那样运行。两个web请求都是成功的,但只有第一个继续处理响应。
第二个延续未完成最后一个给了我结果:
Id = 1, Status = RanToCompletion, Method = "{null}", Result = "System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult]"
结果:
Id = 2, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"
我的问题是我做错了什么,我能做些什么,这样第二个延续就完成了。我还感兴趣的是,使用ContinueWith将任务链接在一起是否被认为是一种良好的做法,或者是否有更好的方法可以做到这一点,而不需要编写一堆笨拙的方法?感谢的帮助
using Newtonsoft.Json.Linq;
var api = new Api();
var order = new Dictionary<string, object>();
await api.MakeRequest(Api.Endpoint.Orders, HttpMethod.Get, null, "?completed=false&page=" + count)
//Look for new Orders
.ContinueWith(ant =>
{
dynamic jsonOrder = JObject.Parse(ant.Result);
JArray data = jsonOrder.data;
//Process Json Response
order.Add("customer_name", (string)data[j]["customer_name"]);
order.Add("product_id", (string)data[j]["product_id"]);
order.Add("order_id", (string)data[j]["order_id"]);
order.Add("timestamp", (int)data[j]["timestamp"]);
//Entries are successfully added
}, TaskContinuationOptions.NotOnFaulted )
//Now get more details about the product
.ContinueWith(async (ant) =>
{
string result = await api.MakeRequest(Api.Endpoint.Product, HttpMethod.Get, null, (string)order["product_id"]);
//The Request succeeds
//This code block does not execute
dynamic json = JObject.Parse(result);
order.Add("deadline", (int)json.data.deadline);
order.Add("price", (string)json.data.price);
order.Add("amount", (int)json.data.amount);
//This code block does not execute
}, TaskContinuationOptions.NotOnFaulted)
//Get some more details about the Customer (isRecurring? etc)
.ContinueWith(async (ant) =>
{
//Some more code here
}
Like@Ben Robinson说,await
的使用会自动将方法的其余部分注册为延续,只有在操作成功时才会执行,否则会引发异常。如果异步操作完成后不需要返回到当前的SynchrionizationContext
,即方法的其余部分将继续在线程池线程上执行,我会更改方法以删除ContinueWith
调用,并考虑使用ConfigureAwait(false)
。你可能也会发现这篇文章很有用。
var api = new Api();
var order = new Dictionary<string, object>();
await api.MakeRequest(Api.Endpoint.Orders, HttpMethod.Get, null, "?completed=false&page=" + count).ConfiugureAwait(false);
//Look for new Orders
dynamic jsonOrder = JObject.Parse(ant.Result);
JArray data = jsonOrder.data;
//Process Json Response
order.Add("customer_name", (string)data[j]["customer_name"]);
order.Add("product_id", (string)data[j]["product_id"]);
order.Add("order_id", (string)data[j]["order_id"]);
order.Add("timestamp", (int)data[j]["timestamp"]);
//Now get more details about the product
string result = await api.MakeRequest(Api.Endpoint.Product, HttpMethod.Get, null, (string)order["product_id"]).ConfiugureAwait(false);
dynamic json = JObject.Parse(result);
order.Add("deadline", (int)json.data.deadline);
order.Add("price", (string)json.data.price);
order.Add("amount", (int)json.data.amount);