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: 
4

1 に答える 1

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();
}
于 2012-04-10T10:28:27.173 に答える