Freigeben über


Ausnahmebehandlung in der Concurrency Runtime

Die Concurrency Runtime übermittelt viele Arten von Fehlern mithilfe der C++-Ausnahmebehandlung.Diese Fehler sind falsche Verwendung der Laufzeit, Runtime-Fehler wie kann, eine Ressource sowie Fehler, die in Arbeitsfunktionen auftreten, die Sie an Aufgaben und für Arbeitsgruppen bereitstellen.Wenn eine Aufgabe oder eine Aufgabengruppe eine Ausnahme auslöst, wird die Laufzeit diese Ausnahme an und an den Kontext gemarshallt, der Aufgabe oder die Aufgabengruppe beendet wird wartet.Bei Komponenten wie bei einfachen Aufgaben und Agents verwaltet die Runtime keine Ausnahmen.In diesen Fällen müssen Sie einen eigenen Mechanismus für die Ausnahmenbehandlung implementieren.In diesem Thema wird beschrieben, wie die Runtime Ausnahmen behandelt, die von den Aufgaben, von Aufgabengruppen, einfachen Aufgaben und asynchronen Agents ausgelöst werden, und wie in Anwendungen auf Ausnahmen reagiert.

Punkte

  • Wenn eine Aufgabe oder eine Aufgabengruppe eine Ausnahme auslöst, wird die Laufzeit diese Ausnahme an und an den Kontext gemarshallt, der Aufgabe oder die Aufgabengruppe beendet wird wartet.

  • Wenn möglich, schließen Sie jeder Aufruf concurrency::task::get und zu concurrency::task::wait mit einem try/catch-Block, um Fehler zu behandeln, die Sie beheben können.Die Laufzeit beendet die Anwendung, wenn eine Aufgabe eine Ausnahme auslöst und diese Ausnahme nicht durch die Aufgabe abgefangen wird, eine seiner Fortsetzungen oder die zentrale App.

  • Ausführungen einer aufgabenbasierte Fortsetzung immer, ist es irrelevant, ob die vorangehende Aufgabengruppe erfolgreich, eine Ausnahme ausgelöst wurde, oder wurde abgebrochen.Eine wertbasierte Fortsetzung wird nicht ausgeführt, wenn die Vorgängeraufgabe oder Löschen auslöst.

  • Da aufgabenbasierte Fortsetzungen immer die Ausführung, prüfen, ob eine Fortsetzung aufgabenbasierte am Ende der Fortsetzungskette hinzugefügt wird.Dies kann helfen, sicherzustellen, dass der Code alle Ausnahmen achtet.

  • Die Laufzeit löst concurrency::task_canceled aus, wenn Sie concurrency::task::get aufrufen und diese Aufgabe abgebrochen wird.

  • Die Runtime verwaltet keine Ausnahmen für einfache Aufgaben und Agents.

In diesem Dokument

  • Aufgaben und Fortsetzungen

  • Aufgabengruppen und parallele Algorithmen

  • Von der Runtime ausgelöste Ausnahmen

  • Mehrere Ausnahmen

  • Abbruch

  • Einfache Aufgaben

  • Asynchrone Agents

Aufgaben und Fortsetzungen

In diesem Abschnitt wird beschrieben, wie die Runtime Ausnahmen behandelt, die von concurrency::task-Objekte und ihre Fortsetzungen ausgelöst werden.Weitere Informationen über die Aufgabe und das Fortsetzungsmodell, finden Sie unter Aufgabenparallelität (Concurrency Runtime).

Wenn Sie eine Ausnahme im Text einer Arbeitsfunktion, die Sie für task ein Objekt, wird diese Ausnahme und die an den Kontext gemarshallt übergeben, der concurrency::task::get oder concurrency::task::wait aufruft.Das Dokument Aufgabenparallelität (Concurrency Runtime) beschreibt aufgabenbasiertes für wertbasierte Fortsetzungen, aber zusammenzufassen, nimmt eine wertbasierte Fortsetzung einen Parameter vom Typ T und aufgabenbasierte eine Fortsetzung akzeptiert einen Parameter vom Typ task<T>.Wenn eine Aufgabe, die ausgelöst wird, eine oder mehrere wertbasierten Fortsetzungen verfügt, werden diese Fortsetzungen nicht geplant, um ausgeführt zu werden.Dieses Verhalten wird im folgenden Beispiel veranschaulicht:

// eh-task.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
    wcout << L"Running a task..." << endl;
    // Create a task that throws.
    auto t = create_task([]
    {
        throw exception();
    });

    // Create a continuation that prints its input value.
    auto continuation = t.then([]
    {
        // We do not expect this task to run because
        // the antecedent task threw.
        wcout << L"In continuation task..." << endl;
    });

    // Wait for the continuation to finish and handle any 
    // error that occurs.
    try
    {
        wcout << L"Waiting for tasks to finish..." << endl;
        continuation.wait();

        // Alternatively, call get() to produce the same result.
        //continuation.get();
    }
    catch (const exception& e)
    {
        wcout << L"Caught exception." << endl;
    }
}
/* Output:
    Running a task...
    Waiting for tasks to finish...
    Caught exception.
*/

Eine Fortsetzung aufgabenbasierte ermöglicht es, jede Ausnahme zu behandeln, die durch die Vorgängeraufgabe ausgelöst wird.Ausführungen einer aufgabenbasierte Fortsetzung immer, ist es irrelevant, dass die Aufgabengruppe erfolgreich, eine Ausnahme ausgelöst wurde, oder wurde abgebrochen.Wenn eine Aufgabe eine Ausnahme auslöst, werden seine Fortsetzungen aufgabenbasierte geplant, um ausgeführt zu werden.Im folgenden Beispiel wird eine Aufgabe veranschaulicht, die immer auslöst.Die Aufgabe verfügt über zwei Fortsetzungen; Ein Steuerelement ist wertbasiert und das andere ist aufgabenbasiert.Die aufgabenbasierte Ausführungen der Ausnahme immer und können daher die Ausnahme abfangen, die durch die Vorgängeraufgabe ausgelöst wird.Wenn das Beispiel auf beide Fortsetzungen wartet, um zu beenden, wird die Ausnahme erneut ausgelöst, da die Aufgabenausnahme immer ausgelöst wird, wenn task::get oder task::wait aufgerufen wird.

// eh-continuations.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{    
    wcout << L"Running a task..." << endl;
    // Create a task that throws.
    auto t = create_task([]() -> int
    {
        throw exception();
        return 42;
    });

    //
    // Attach two continuations to the task. The first continuation is  
    // value-based; the second is task-based.

    // Value-based continuation.
    auto c1 = t.then([](int n)
    {
        // We don't expect to get here because the antecedent 
        // task always throws.
        wcout << L"Received " << n << L'.' << endl;
    });

    // Task-based continuation.
    auto c2 = t.then([](task<int> previousTask)
    {
        // We do expect to get here because task-based continuations
        // are scheduled even when the antecedent task throws.
        try
        {
            wcout << L"Received " << previousTask.get() << L'.' << endl;
        }
        catch (const exception& e)
        {
            wcout << L"Caught exception from previous task." << endl;
        }
    });

    // Wait for the continuations to finish.
    try
    {
        wcout << L"Waiting for tasks to finish..." << endl;
        (c1 && c2).wait();
    }
    catch (const exception& e)
    {
        wcout << L"Caught exception while waiting for all tasks to finish." << endl;
    }
}
/* Output:
    Running a task...
    Waiting for tasks to finish...
    Caught exception from previous task.
    Caught exception while waiting for all tasks to finish.
*/

Es wird empfohlen, aufgabenbasierte Fortsetzungen verwenden, um Ausnahmen abzufangen, dass Sie in der Lage sind zu behandeln.Da aufgabenbasierte Fortsetzungen immer die Ausführung, prüfen, ob eine Fortsetzung aufgabenbasierte am Ende der Fortsetzungskette hinzugefügt wird.Dies kann helfen, sicherzustellen, dass der Code alle Ausnahmen achtet.Im folgenden Beispiel wird eine grundlegende wertbasierte Fortsetzungskette an.Die dritte Aufgabe in den Kettenwürfen und daher keine wertbasierten Fortsetzungen, deren folgen, werden nicht ausgeführt.Es ist die endgültige Fortsetzung aufgabenbasiert und daher immer ausgeführt.Diese endgültige Fortsetzung behandelt die Ausnahme, die durch die dritte Aufgabe ausgelöst wird.

Es wird empfohlen, die bestimmtsten Ausnahmen abfangen, die Sie können.Sie können diese endgültige aufgabenbasierte Fortsetzung auslassen, wenn Sie nicht die spezifischen Ausnahmen abzufangen, haben.Jede Ausnahme wird nicht behandelt und kann die Anwendung beenden.

// eh-task-chain.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
    int n = 1;
    create_task([n]
    {
        wcout << L"In first task. n = ";
        wcout << n << endl;

        return n * 2;

    }).then([](int n)
    {
        wcout << L"In second task. n = ";
        wcout << n << endl;

        return n * 2;

    }).then([](int n)
    {
        wcout << L"In third task. n = ";
        wcout << n << endl;

        // This task throws.
        throw exception();
        // Not reached.
        return n * 2;

    }).then([](int n)
    {
        // This continuation is not run because the previous task throws.
        wcout << L"In fourth task. n = ";
        wcout << n << endl;

        return n * 2;

    }).then([](task<int> previousTask)
    {
        // This continuation is run because it is value-based.
        try
        {
            // The call to task::get rethrows the exception.
            wcout << L"In final task. result = ";
            wcout << previousTask.get() << endl;
        }
        catch (const exception&)
        {
            wcout << L"<exception>" << endl;
        }
    }).wait();
}
/* Output:
    In first task. n = 1
    In second task. n = 2
    In third task. n = 4
    In final task. result = <exception>
*/
TippTipp

Sie können die concurrency::task_completion_event::set_exception-Methode verwenden, um eine Ausnahme mit einem Aufgabenabschlussereignis zuzuordnen.Das Dokument Aufgabenparallelität (Concurrency Runtime) beschreibt die concurrency::task_completion_event-Klasse ausführlich.

concurrency::task_canceled ist ein wichtiger Ablaufausnahmetyp, der zu task verknüpft.Die Laufzeit löst task_canceled aus, wenn Sie task::get aufrufen und diese Aufgabe abgebrochen wird.(Umgekehrt, gibt task::waittask_status::canceled zurück und löst nicht aus.) Sie können diese Ausnahme aus einer aufgabenbasierte Fortsetzung abfangen und behandeln oder, wenn Sie task::get aufrufen.Weitere Informationen zu den Aufgabenabbruch, finden Sie unter Abbruch in der PPL.

WarnhinweisVorsicht

Lösen Sie nie task_canceled aus dem Code aus.Aufruf concurrency::cancel_current_task stattdessen.

Die Laufzeit beendet die Anwendung, wenn eine Aufgabe eine Ausnahme auslöst und diese Ausnahme nicht durch die Aufgabe abgefangen wird, eine seiner Fortsetzungen oder die zentrale App.Wenn die Anwendung abstürzt, können Sie Visual Studio so konfigurieren, dass zu unterbrechen, wenn C++-Ausnahmen ausgelöst werden.Nachdem Sie den Speicherort des Ausnahme bestimmen, verwenden Sie eine aufgabenbasierte Fortsetzung, um sie zu behandeln.

Der Abschnitt der Runtime ausgelöste Ausnahmen in diesem Dokument wird beschrieben, wie mit Laufzeitausnahmen ausführlich funktioniert.

Anfang[]

Aufgabengruppen und parallele Algorithmen

In diesem Abschnitt wird beschrieben, wie die Runtime Ausnahmen behandelt, die von Aufgabengruppen ausgelöst werden.Dieser Abschnitt gilt auch für parallele Algorithmen wie concurrency::parallel_for, da diese Algorithmen auf Aufgabengruppen aufbauen.

WarnhinweisVorsicht

Es ist wichtig, dass Sie die Auswirkungen von Ausnahmen auf abhängige Aufgaben verstehen.Empfohlene Vorgehensweisen zum Verwenden der Ausnahmebehandlung bei Aufgaben oder parallelen Algorithmen finden Sie im entsprechenden Abschnitt der Parallel Patterns Library unter Understand how Cancellation and Exception Handling Affect Object Destruction.

Weitere Informationen zu Aufgabengruppen finden Sie unter Aufgabenparallelität (Concurrency Runtime).Weitere Informationen zu parallelen Algorithmen finden Sie unter Parallele Algorithmen.

Wenn Sie eine Ausnahme im Text einer Arbeitsfunktion, die Sie zu einem concurrency::task_group oder concurrency::structured_task_group-Objekt, von der Laufzeit gespeichert und an den Kontext gemarshallt es übergeben, der concurrency::task_group::wait, concurrency::structured_task_group::wait, concurrency::task_group::run_and_wait oder concurrency::structured_task_group::run_and_wait aufruft.Darüber hinaus werden von der Runtime auch alle aktiven Aufgaben in der Aufgabengruppe (sowie alle aktiven Aufgaben in untergeordneten Aufgabengruppen) beendet sowie alle noch nicht gestarteten Aufgaben verworfen.

Im folgenden Beispiel wird die grundlegende Struktur einer Arbeitsfunktion dargestellt, die eine Ausnahme auslöst.Im Beispiel werden die Werte von zwei point-Objekten mithilfe eines task_group-Objekts parallel ausgegeben.Die print_point-Arbeitsfunktion gibt die Werte eines point-Objekts an der Konsole aus.Die Arbeitsfunktion löst eine Ausnahme aus, wenn der Eingabewert NULL ist.Diese Ausnahme wird von der Runtime gespeichert und an den Kontext gemarshallt, der task_group::wait aufruft.

// eh-task-group.cpp
// compile with: /EHsc
#include <ppl.h>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

// Defines a basic point with X and Y coordinates.
struct point
{
   int X;
   int Y;
};

// Prints the provided point object to the console.
void print_point(point* pt)
{
   // Throw an exception if the value is NULL.
   if (pt == NULL)
   {
      throw exception("point is NULL.");
   }

   // Otherwise, print the values of the point.
   wstringstream ss;
   ss << L"X = " << pt->X << L", Y = " << pt->Y << endl;
   wcout << ss.str();
}

int wmain()
{
   // Create a few point objects.
   point pt = {15, 30};
   point* pt1 = &pt;
   point* pt2 = NULL;

   // Use a task group to print the values of the points.
   task_group tasks;

   tasks.run([&] {
      print_point(pt1);
   });

   tasks.run([&] {
      print_point(pt2);
   });

   // Wait for the tasks to finish. If any task throws an exception,
   // the runtime marshals it to the call to wait.
   try
   {
      tasks.wait();
   }
   catch (const exception& e)
   {
      wcerr << L"Caught exception: " << e.what() << endl;
   }
}

Folgende Ergebnisse werden zurückgegeben:

X = 15, Y = 30
Caught exception: point is NULL.

Ein umfassendes Beispiel für die Verwendung der Ausnahmebehandlung in einer Aufgabengruppe finden Sie unter Gewusst wie: Verwenden der Ausnahmebehandlung zum Verlassen einer Parallel-Schleife.

Anfang[]

Von der Runtime ausgelöste Ausnahmen

Eine Ausnahme kann von einem Aufruf der Runtime ausgelöst werden.Die meisten Ausnahmetypen, außer concurrency::task_canceled und concurrency::operation_timed_out, geben einen Programmierfehler.Diese Fehler sind in der Regel nicht behebbar und dürfen daher durch Anwendungscode weder abgefangen noch behandelt werden.Es wird empfohlen, bei der Diagnose von Programmierfehlern nur nicht behebbare Fehler im Anwendungscode abzufangen oder zu behandeln.Die von der Runtime definierten Ausnahmetypen zu kennen, erleichtert jedoch die Diagnose von Programmierfehlern.

Der Mechanismus für die Ausnahmenbehandlung ist bei Ausnahmen, die durch die Runtime ausgelöst werden, derselbe wie bei Ausnahmen, der durch Arbeitsfunktionen ausgelöst werden.Beispielsweise löst die concurrency::receive-Funktion operation_timed_out aus, wenn eine Nachricht nicht im angegebenen Zeitraum empfangen wird.Wenn receive eine Ausnahme in einer Arbeitsfunktion auslöst, die an eine Aufgabengruppe übergeben wird, wird diese Ausnahme von der Runtime gespeichert und an den Kontext gemarshallt, der task_group::wait, structured_task_group::wait, task_group::run_and_wait oder structured_task_group::run_and_wait aufruft.

Im folgenden Beispiel wird der concurrency::parallel_invoke Algorithmus, um zwei Aufgaben parallel auszuführen.Die erste Aufgabe wartet fünf Sekunden und sendet dann eine Nachricht an einen Nachrichtenpuffer.Die zweite Aufgabe wartet mithilfe der receive-Funktion drei Sekunden auf eine Nachricht vom selben Nachrichtenpuffer.Die receive-Funktion löst die operation_timed_out-Ausnahme aus, wenn die Nachricht nicht im angegebenen Zeitraum empfangen wird.

// eh-time-out.cpp
// compile with: /EHsc
#include <agents.h>
#include <ppl.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   single_assignment<int> buffer;
   int result;

   try
   {
      // Run two tasks in parallel.
      parallel_invoke(
         // This task waits 5 seconds and then sends a message to 
         // the message buffer.
         [&] {
            wait(5000); 
            send(buffer, 42);
         },
         // This task waits 3 seconds to receive a message.
         // The receive function throws operation_timed_out if it does 
         // not receive a message in the specified time period.
         [&] {
            result = receive(buffer, 3000);
         }
      );

      // Print the result.
      wcout << L"The result is " << result << endl;
   }
   catch (operation_timed_out&)
   {
      wcout << L"The operation timed out." << endl;
   }
}

Folgende Ergebnisse werden zurückgegeben:

The operation timed out.

Um sicherzustellen, dass die Anwendung ordnungsgemäß beendet wird, muss der Code beim Aufrufen der Runtime Ausnahmen behandeln.Behandeln Sie auch Ausnahmen, wenn Sie externen Code wie etwa die Bibliothek eines Drittanbieters aufrufen, der die Concurrency Runtime verwendet.

Anfang[]

Mehrere Ausnahmen

Wenn eine Aufgabe oder paralleler Algorithmus mehrere Ausnahmen empfängt, wird nur eine dieser Ausnahmen von der Runtime an den aufrufenden Kontext gemarshallt.Dabei kann nicht vorhergesagt werden, welche Ausnahme von der Runtime gemarshallt wird.

Im folgenden Beispiel werden mithilfe des parallel_for-Algorithmus Zahlen an der Konsole ausgegeben.Es wird eine Ausnahme ausgegeben, wenn der Eingabewert kleiner als ein Mindestwert oder größer als ein Maximalwert ist.In diesem Beispiel können mehrere Arbeitsfunktionen eine Ausnahme auslösen.

// eh-multiple.cpp
// compile with: /EHsc
#include <ppl.h>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

int wmain()
{
   const int min = 0;
   const int max = 10;

   // Print values in a parallel_for loop. Use a try-catch block to 
   // handle any exceptions that occur in the loop.
   try
   {
      parallel_for(-5, 20, [min,max](int i)
      {
         // Throw an exeception if the input value is less than the 
         // minimum or greater than the maximum.

         // Otherwise, print the value to the console.

         if (i < min)
         {
            stringstream ss;
            ss << i << ": the value is less than the minimum.";
            throw exception(ss.str().c_str());
         }
         else if (i > max)
         {
            stringstream ss;
            ss << i << ": the value is greater than than the maximum.";
            throw exception(ss.str().c_str());
         }
         else
         {
            wstringstream ss;
            ss << i << endl;
            wcout << ss.str();
         }
      });
   }
   catch (exception& e)
   {
      // Print the error to the console.
      wcerr << L"Caught exception: " << e.what() << endl;
   }  
}

Nachfolgend wird eine Beispielausgabe für dieses Beispiel angezeigt.

8
2
9
3
10
4
5
6
7
Caught exception: -5: the value is less than the minimum.

Anfang[]

Abbruch

Nicht alle Ausnahmen geben einen Fehler an.Ein Suchalgorithmus kann beispielsweise mithilfe der Ausnahmenbehandlung die zugehörige Aufgabe beenden, sobald das Ergebnis gefunden ist.Weitere Informationen zum Verwenden von Abbruchmechanismen im Code finden Sie unter Abbruch in der PPL.

Anfang[]

Einfache Aufgaben

Eine einfache Aufgabe ist eine Aufgabe, die Sie direkt von einem concurrency::Scheduler-Objekt planen.Einfache Aufgaben erfordern einen geringeren Aufwand als gewöhnliche Aufgaben.Die Runtime fängt jedoch keine Ausnahmen ab, die von einfachen Aufgaben ausgelöst werden.Stattdessen wird die Ausnahme vom Handler für nicht behandelte Ausnahmen abgefangen, der den Prozess standardmäßig beendet.Verwenden Sie daher in der Anwendung einen entsprechenden Fehlerbehandlungsmechanismus.Weitere Informationen zu einfachen Aufgaben finden Sie unter Taskplaner (Concurrency Runtime).

Anfang[]

Asynchrone Agents

Die Runtime verwaltet wie bei einfachen Aufgaben auch keine Ausnahmen, die von asynchronen Agents ausgelöst werden.

Das folgende Beispiel zeigt eine Möglichkeit, die Behandlung von Ausnahmen in einer Klasse, die von concurrency::agent abgeleitet.In diesem Beispiel wird die points_agent-Klasse definiert.Die points_agent::run-Methode liest point-Objekte aus dem Nachrichtenpuffer und gibt sie an der Konsole aus.Die run-Methode löst beim Empfang eines NULL-Zeigers eine Ausnahme aus.

Die run-Methode schließt alle Arbeiten in einen try-catch-Block ein.Die Ausnahme wird vom catch-Block in einem Nachrichtenpuffer gespeichert.Die Anwendung überprüft, ob im Agent ein Fehler aufgetreten ist. Hierzu wird dieser Puffer nach Abschluss des Agents gelesen.

// eh-agents.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Defines a point with x and y coordinates.
struct point
{
   int X;
   int Y;
};

// Informs the agent to end processing.
point sentinel = {0,0};

// An agent that prints point objects to the console.
class point_agent : public agent
{
public:
   explicit point_agent(unbounded_buffer<point*>& points)
      : _points(points)
   { 
   }

   // Retrieves any exception that occurred in the agent.
   bool get_error(exception& e)
   {
      return try_receive(_error, e);
   }

protected:
   // Performs the work of the agent.
   void run()
   {
      // Perform processing in a try block.
      try
      {
         // Read from the buffer until we reach the sentinel value.
         while (true)
         {
            // Read a value from the message buffer.
            point* r = receive(_points);

            // In this example, it is an error to receive a 
            // NULL point pointer. In this case, throw an exception.
            if (r == NULL)
            {
               throw exception("point must not be NULL");
            }
            // Break from the loop if we receive the 
            // sentinel value.
            else if (r == &sentinel)
            {
               break;
            }
            // Otherwise, do something with the point.
            else
            {
               // Print the point to the console.
               wcout << L"X: " << r->X << L" Y: " << r->Y << endl;
            }
         }
      }
      // Store the error in the message buffer.
      catch (exception& e)
      {
         send(_error, e);
      }

      // Set the agent status to done.
      done();
   }

private:
   // A message buffer that receives point objects.
   unbounded_buffer<point*>& _points;

   // A message buffer that stores error information.
   single_assignment<exception> _error;
};

int wmain()
{  
   // Create a message buffer so that we can communicate with
   // the agent.
   unbounded_buffer<point*> buffer;

   // Create and start a point_agent object.
   point_agent a(buffer);
   a.start();

   // Send several points to the agent.
   point r1 = {10, 20};
   point r2 = {20, 30};
   point r3 = {30, 40};

   send(buffer, &r1);
   send(buffer, &r2);
   // To illustrate exception handling, send the NULL pointer to the agent.
   send(buffer, reinterpret_cast<point*>(NULL));
   send(buffer, &r3);
   send(buffer, &sentinel);

   // Wait for the agent to finish.
   agent::wait(&a);

   // Check whether the agent encountered an error.
   exception e;
   if (a.get_error(e))
   {
      cout << "error occurred in agent: " << e.what() << endl;
   }

   // Print out agent status.
   wcout << L"the status of the agent is: ";
   switch (a.status())
   {
   case agent_created:
      wcout << L"created";
      break;
   case agent_runnable:
      wcout << L"runnable";
      break;
   case agent_started:
      wcout << L"started";
      break;
   case agent_done:
      wcout << L"done";
      break;
   case agent_canceled:
      wcout << L"canceled";
      break;
   default:
      wcout << L"unknown";
      break;
   }
   wcout << endl;
}

Folgende Ergebnisse werden zurückgegeben:

X: 10 Y: 20
X: 20 Y: 30
error occurred in agent: point must not be NULL
the status of the agent is: done

Da sich der try-catch-Block außerhalb der while-Schleife befindet, beendet der Agent die Verarbeitung, sobald der erste Fehler auftritt.Wenn sich der try-catch-Block innerhalb der while-Schleife befände, würde der Agent die Verarbeitung nach dem Auftreten eines Fehlers fortsetzen.

In diesem Beispiel werden Ausnahmen in einem Nachrichtenpuffer gespeichert, damit eine andere Komponente den Agent beim Ausführen auf Fehler überwachen kann.In diesem Beispiel wird ein concurrency::single_assignment-Objekt, um den Fehler zu speichern.Wenn ein Agent mehrere Ausnahmen behandelt speichert die single_assignment-Klasse nur die erste Nachricht, die an sie übergeben wird.Um nur die letzte Ausnahme zu speichern, verwenden Sie die concurrency::overwrite_buffer-Klasse.Um alle Ausnahmen zu speichern, verwenden Sie die concurrency::unbounded_buffer-Klasse.Weitere Informationen zu diesen Nachrichtenblöcken finden Sie unter Asynchrone Nachrichtenblöcke.

Weitere Informationen zu asynchronen Agents finden Sie unter Asynchrone Agents.

Anfang[]

Zusammenfassung

Anfang[]

Siehe auch

Konzepte

Concurrency Runtime

Aufgabenparallelität (Concurrency Runtime)

Parallele Algorithmen

Abbruch in der PPL

Taskplaner (Concurrency Runtime)

Asynchrone Agents