次のようにレイアウトするコードがいくつかあります。
クラス1
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 を受け取り、それを Task で実行し、ContinueWith ブロックで応答を取得し、応答を に解析しList<T>
、 を返すためだけに存在しList<T>
ます。
Class1 で続行する前に InvokeTaskMagic メソッドから結果を取得する必要があるため、Class1 の TaskHelper への呼び出しをタスクでラップしました (つまり、class1 での次のステップは、を使用することList<T>
です。コードのコメントにあるように、私の問題はTaskHelper クラスの InvokeTaskMagic メソッドからの応答を待機していないため、class1 の Task は毎回空のリストを返します。
これは期待されていますか?TaskHelper.InvokeTaskMagic が戻るまで getSessionsTask を待機させる方法はありますか?
更新: 作業コードは次のとおりです。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);
}
});
});