gpt4 book ai didi

c# - 使用任务索引超出范围异常

转载 作者:行者123 更新时间:2023-11-30 17:04:27 25 4
gpt4 key购买 nike

我正在使用 Task.FromAsync 和 Task.ContinueWith 方法来完成我的工作。我在我的程序中使用了一个列表,当我运行它时,它给了我一个索引超出范围异常。但是,当我通过调试器时,它会运行并完成。将任务与循环和列表一起使用时,我是否遗漏了什么或它们的运行方式不同?

public int TimerCounter = 0;
public IList<WebsiteResult>webResult = new List<WebsiteResult>();

public void sendRequest(){
foreach(Website web in TempVar._allWebsites)
{
webResult.Add(new WebSiteResult {});
try
{
pageCheck(web);
webResult.ElementAt(TimerCounter).RequestSentTime = DateTime.Now.ToString();
if(webResult.ElementAt(TimerCounter).SystemStatus == null)
webResult.ElementAt(TimerCounter).SystemStatus = "";

TimeCounter++;
}
}



public void pageCheck(){
IAsyncResult asyncResult;
Uri uri = new Uri(TempURL); //TempUrl is assigned a string beforehand
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);
try{
Task<WebResponse> task = Task.Factory.FromAsync(
myReq.BeginGetResponse,
asyncResult => myReq.EndGetResponse(asyncResult),
(Object)null);

task.ContinueWith(t =>
{
var responseCode = (HttpWebResponse)t.Result;
ReadStreamFromResponse(t.Result);
if(responseCode.StatusCode == HttpStatusCode.OK){
webResult.ElementAt(TimerCounter).ResponseStatusCode = "Up"; //Error occurs here
reponseCode.Close();
}
}
);
}
//catch exceptions
}

private String ReadStreamFromResponse(WebResponse response) {
StreamReader responseStream = new StreamReader(response.GetResponseStream());
string str = responseStream.ReadToEnd();
return str;
}

最佳答案

这是因为您对 pageCheck() 的调用设置了一个延续,它将在 Task 结束/完成时运行。但是,对 pageCheck() 方法的调用将在设置和结束您的 Task 后立即返回给调用者 (sendRequest()) >。您的 Task 将需要时间在后台线程池线程上执行,但会很快将控制返回给 sendRequest(),然后它会尝试访问您的 IList 将没有元素,因为这些元素是在延续中填充的。这可能工作有时取决于线程池优化器如何分派(dispatch)Task 以及任务需要多长时间。如果您逐步使用调试器,这会影响 Task 的触发方式,并会影响操作的顺序 - 因此 同样会影响这些操作的结果。

我的建议是把你的

task.ContinueWith(t =>
{
var responseCode = (HttpWebResponse)t.Result;
ReadStreamFromResponse(t.Result);
if(responseCode.StatusCode == HttpStatusCode.OK)
{
webResult.ElementAt(TimerCounter).ResponseStatusCode = "Up"; //Error occurs here
reponseCode.Close();
}

webResult.ElementAt(TimerCounter).RequestSentTime = DateTime.Now.ToString();
if(webResult.ElementAt(TimerCounter).SystemStatus == null)
webResult.ElementAt(TimerCounter).SystemStatus = "";
TimeCounter++;
});

进入 pageCheck() 内的延续。另一种选择是创建另一种方法,将此过程包装在“更高级别的任务”中,您将设置 Task 并在 sendRequest() 中继续方法代替。

请注意,在这种情况下使用锁对您没有帮助,因为您不知道何时会施加锁。它可能不会影响执行顺序,您的问题仍然存在。

希望对您有所帮助。

关于c# - 使用任务索引超出范围异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17449926/

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