gpt4 book ai didi

c# - 2 级 Task.ContinueWith 的意外行为

转载 作者:太空狗 更新时间:2023-10-30 00:26:00 25 4
gpt4 key购买 nike

我有一些代码是这样布局的:

Class1

Task<List<ConfSession>> getSessionsTask = Task.Factory.StartNew(() =>
{
var confSessions =
TaskHelper<ConfSession>.InvokeTaskMagic(request);
//PROBLEM - THIS CODE RACES TO THE NEXT LINE
//BEFORE confSessions IS POPULATED FROM THE LINE ABOVE - IE
//confSessions IS ALWAYS AN EMPTY LIST
//WHEN IT'S RETURNED
return confSessions;
}
);

Class2(任务助手)

//methods
public static List<T> InvokeTaskMagic(HttpWebRequest request)
{
var resultList = new List<T>();

Task<WebResponse> task1 = Task<WebResponse>.Factory.FromAsync(
(callback, o) => ((HttpWebRequest)o).BeginGetResponse(callback, o)
, result => ((HttpWebRequest)result.AsyncState).EndGetResponse(result)
, request);

task1.ContinueWith((antecedent) =>
{
if (antecedent.IsFaulted)
{
return;
}

WebResponse webResponse;
try
{
webResponse = task1.Result;
}
catch (AggregateException ex1)
{
throw ex1.InnerException;
}

string responseString;

using (var response = (HttpWebResponse)webResponse)
{
using (Stream streamResponse = response.GetResponseStream())
{
StreamReader reader = new StreamReader(streamResponse);
responseString = reader.ReadToEnd();
reader.Close();
}
}

if (responseString != null)
{
resultList =
JsonConvert.DeserializeObject<List<T>>(responseString);
}
});

return resultList;
}

TaskHelper 是我创建的一个类,用于标准化我在多个方法中拥有的一堆冗余任务代码。它的存在只是为了获取一个 HttpWebRequest,在任务中执行它,在 ContinueWith block 中获取响应,将响应解析为 List<T>。 ,并返回 List<T> .

我将 Class1 对 TaskHelper 的调用包装在任务中,因为我需要在继续 class1 之前从 InvokeTaskMagic 方法获取结果(即 class1 的下一步是使用 List<T> 。正如它在评论中所说代码,我的问题是 class1 中的任务每次都返回一个空列表,因为它没有等待 TaskHelper 类中的 InvokeTaskMagic 方法的响应。

这是预期的吗?有没有办法让 getSessionsTask 等待返回,直到 TaskHelper.InvokeTaskMagic 返回?

更新:工作代码如下 - 感谢 Servy 的帮助。

public static class TaskHelper<T> where T : class
{
//methods
public static Task<List<T>> InvokeTaskMagic(HttpWebRequest request)
{
var resultList = new List<T>();

Task<WebResponse> task1 = Task<WebResponse>.Factory.FromAsync(
(callback, o) => ((HttpWebRequest)o).BeginGetResponse(callback, o)
, result => ((HttpWebRequest)result.AsyncState).EndGetResponse(result)
, request);

return task1.ContinueWith<List<T>>((antecedent) =>
{
if (antecedent.IsFaulted)
{
return new List<T>();
}

WebResponse webResponse;
try
{
webResponse = task1.Result;
}
catch (AggregateException ex1)
{
throw ex1.InnerException;
}

string responseString;

using (var response = (HttpWebResponse)webResponse)
{
using (Stream streamResponse = response.GetResponseStream())
{
StreamReader reader = new StreamReader(streamResponse);
responseString = reader.ReadToEnd();
reader.Close();
}
}

if (responseString != null)
{
return JsonConvert.DeserializeObject<List<T>>(responseString);
}
else
{
return new List<T>();
}
});
}
}

InvokeTaskMagic 方法是这样调用的:

var getCommentsAboutTask = Task.Factory.StartNew(() =>
{
var comments = TaskHelper<Comment>.InvokeTaskMagic(request);
return comments;
});

getCommentsAboutTask.ContinueWith((antecedent) =>
{
if (antecedent.IsFaulted)
{ return; }

var commentList = antecedent.Result.Result;
UIThread.Invoke(() =>
{
foreach (Comment c in commentList)
{
AllComments.Add(c);
GetCommentRelatedInfo(c);
}
});
});

最佳答案

Is this expected? Is there a way to make my class1.task1 continueblock wait for my class2.task2 continueblock?

当然,只需在第二个任务的继续而不是第一个任务上调用 ContinueWith

如果您需要等到两者都完成,您可以使用 Task.Factory.ContinueWhenAll

关于c# - 2 级 Task.ContinueWith 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13955631/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com