2012-04-10 40 views
2

我在多线程和事件中遇到了一些问题。多线程和事件

我有以下函数执行线程数:

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: 
+0

'm_allProjects'最好是线程安全的集合。 – 2012-04-10 10:19:41

+0

'GetProjectInfo()'是否以某种方式启动另一个线程?否则,你应该先把事件连接起来。 – 2012-04-10 10:23:38

+0

谢谢Henk,我也应该看看。但我首先想解决我的主要问题:) – 2012-04-10 10:23:44

回答

1

AggregateExceptionsTasks抛出,但使用的是Threads

无论如何,阻塞线程,直到事件处理程序运行时,你可以使用一个ManualResetEvent

private void GetProjectInformation(object obj) 
{ 
    ... 
    ProjectConnectionManager connectionManager = new ProjectConnectionManager(); 

    var mre = new ManualResetEvent(false); 

    connectionManager.InfoReceived += delegate(...) 
    { 
     ... 
     mre.Set(); 
    }; 

    connectionManager.GetProjectInfo(filter); 

    mre.WaitOne(); 
} 
+0

我试过这个解决方案,但它不起作用。那么还有什么可能是错误的? – 2012-04-10 10:31:03

+0

别人? – 2012-04-10 13:06:23

+0

不知何故,我可以通过将.Continue放在1行上而不是像我先做的那样在新行中解决问题。非常奇怪的情况。无论如何谢谢你! – 2012-04-11 06:48:13