2012-04-10 9 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 += ... 

Есть ли решение этой проблемы? Можете ли вы дать мне код, пожалуйста?

Edit:

Это метод 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' должны лучше быть поточно-коллекция. –

+0

Создает ли 'GetProjectInfo()' какой-нибудь другой поток? В противном случае вы должны сначала подключить мероприятие. –

+0

Спасибо Хенк, я тоже должен был посмотреть на это. Но я сначала хотел бы решить мою основную проблему :) –

ответ

1

AggregateExceptions брошены на Tasks, но вы используете 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

Я пробовал это решение, но оно не работает. Что еще может быть неправильно тогда? –

+0

Кто-нибудь еще? –

+0

Как-то я мог решить проблему, поставив .Continue на 1 строку, а не на новую строку, как я сделал в первую очередь. Очень странная ситуация. Все равно спасибо всем! –

 Смежные вопросы

  • Нет связанных вопросов^_^