2012-04-10 58 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