【发布时间】:2012-04-10 10:11:10
【问题描述】:
我在多线程和事件方面遇到了一些问题。
我有以下在几个线程中执行的函数:
private void GetProjectInformation(object obj)
{
//Casten
//string projectName = (string)obj;
FilterOptions filter = (FilterOptions)obj;
ProjectConnectionManager connectionManager = new ProjectConnectionManager();
connectionManager.GetProjectInfo(filter);
connectionManager.InfoReceived += delegate(object sender, ProjectInfoEventArgs e)
{
//Geupdate resultaat in de collection vervangen
int index = 0;
bool found = false;
m_dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
foreach (ProjectInfo projectInfo in m_allProjects)
{
if (String.Equals(projectInfo.ProjectName, e.ProjectInfo.ProjectName))
{
found = true;
ProjectInfo result = e.ProjectInfo;
m_allProjects[index] = e.ProjectInfo;
break;
}
index++;
}
//Niet gevonden
if (!found)
{
m_allProjects.Add(e.ProjectInfo);
}
}));
};
}
它是这样调用的:
foreach (FilterOptions opt in m_projectsToShow)
{
Thread thread =
new Thread(new ParameterizedThreadStart(GetProjectInformation));
thread.Start(opt);
}
我面临的问题(我认为)是在
connectionManager.GetProjectInfo(filter);
我的线程取消了。我收到一个 AggregateException,它告诉我任务已关闭,所以我想这一定是问题所在。我想要实现的是以下。我的函数,因此当前线程,必须阻塞,直到该事件被触发:
connectionManager.InfoReceived += ...
有什么解决办法吗?请给我一些代码吗?
编辑:
这是 GetProjectInfo 方法:
public void GetProjectInfo(FilterOptions filter)
{
ProjectInfo result = new ProjectInfo();
try
{
var task = m_httpClient.PostAsync(string.Format("api/project"), new ObjectContent<FilterOptions>(filter, XmlMediaTypeFormatter.DefaultMediaType));
task.ContinueWith(r =>
{
try
{
r.Wait();
if (r.Result.IsSuccessStatusCode)
{
Console.WriteLine("Project " + filter.ProjectName + " was succesfull...");
r.Result.Content.ReadAsAsync<ProjectInfo>().ContinueWith(l =>
{
result = l.Result;
OnProjectInfoReceived(new ProjectInfoEventArgs(result));
});
}
else
{
Console.WriteLine("Project " + filter.ProjectName + " failed!");
}
}
catch (AggregateException ex)
{
Console.WriteLine(ex.ToString());
}
}).Wait(m_httpClient.Timeout);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
我在那里得到了 AggregateException。
这是个例外:
System.AggregateException was caught
Message=One or more errors occurred.
Source=mscorlib
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.get_Result()
at Dashboard.Utils.ProjectConnectionManager.<>c__DisplayClass8.<GetProjectInfo>b__5(Task`1 r) in C:\Users\xxx\Documents\My Own Documents\xxx\ProjectConnectionManager.cs:line 79
InnerException: System.Threading.Tasks.TaskCanceledException
Message=A task was canceled.
InnerException:
【问题讨论】:
-
m_allProjects最好是线程安全的集合。 -
GetProjectInfo()是否以某种方式启动另一个线程?否则你应该先挂起事件。 -
谢谢 Henk,我也应该看看。但我首先想解决我的主要问题:)
-
我编辑了问题并添加了 GetProjectsInfo 方法,该方法本身包含一个任务(异步)。我尝试先连接事件,然后调用 GetProjectInformation(),但问题仍然存在。
-
我也更新了我的帖子,但也有例外。谢谢
标签: c# multithreading dotnet-httpclient