Problembehandlung bei Ausnahmen: System.InvalidOperationException
Ein InvalidOperationException wird ausgelöst, wenn eine Methode eines Objekts aufgerufen wird, wenn der Zustand des Objekts den Methodenaufruf nicht unterstützen kann. Die Ausnahme wird auch ausgelöst, wenn eine Methode versucht, die Benutzeroberfläche von einem Thread, der sich nicht im Hauptfenster oder UI-Thread befindet, zu bearbeiten.
Wichtig
Da InvalidOperationExceptions in einer Vielzahl von Bedingungen ausgelöst werden kann, ist es wichtig, die Message gelesen und verstanden haben, die im Ausnahmen-Assistent angezeigt werden.
In diesem Artikel
Eine auf einem UI-Thread-externen ausgeführte Methode aktualisiert die Benutzeroberfläche
Eine Anweisung in einer Foreach (For Each in Visual Basic)-Block ändert die Sammlung, die sie durchläuft
Ein Typ Nullable < T >, der null ist, wird in T umgewandelt.
Eine System.Linq.Enumerable-Methode wird für eine leere Auflistung aufgerufen.
Verwandte Artikel
Die Codebeispiele in diesem Artikel zeigen Ihnen, wie einige häufige InvalidOperationException Ausnahmen in Ihrer Anwendung auftreten können. Wie Sie Probleme behandeln, hängt von der besonderen Situation ab. Wenn die Ausnahme für die Funktionalität Ihrer Anwendung schädlich ist, möchten Sie möglicherweise ein try … catch (Try .. Catch in Visual Basic) Konstrukt verwenden, um die Ausnahme zu erfassen und den Status der Anwendung vor dem Beenden bereinigen. Aber andere InvalidOperationException können erwartet und vermieden werden. Die überarbeitete Methodenbeispiele zeigen Sie einigen dieser Techniken angezeigt.
Eine auf einem UI-Thread-externen ausgeführte Methode aktualisiert die Benutzeroberfläche
Verursacht eine InvalidOperationException mit einem UI-Update von einem nicht-UI-Thread | Vermeiden von InvalidOperationExceptions in nicht-UI-Threads
Die meisten .NET GUI (grafische Benutzeroberfläche) Anwendungs-Frameworks, wie z. B. Windows Forms und Windows Presentation Foundation (WPF) ermöglichen Ihnen den Zugriff auf GUI-Objekte nur aus dem Thread, der die Benutzeroberfläche (denMain- oder UI-Thread). Ein InvalidOperationException wird ausgelöst, wenn Sie versuchen, auf ein Element der Benutzeroberfläche von einem anderen Thread zuzugreifen, der nicht der UI-Thread ist.
Verursacht eine InvalidOperationException mit einem UI-Update von einem nicht-UI-Thread
Hinweis
Die folgenden Beispiele verwenden die Aufgabenbasiertes asynchrones Muster (TAP, Task-based Asynchronous Pattern), um nicht-UI-Threads zu erstellen.Die Beispiele gelten jedoch auch für alle relevanten Muster für die asynchrone Programmierung.
In diesen Beispielen ruft der ThreadsExampleBtn_Click Ereignishandler die DoSomeWork-Methode zweimal auf. Der erste Aufruf der Methode (DoSomeWork(20); wird synchron ausgeführt und erfolgreich abgeschlossen. Aber der zweite Aufruf (Task.Run( () => { DoSomeWork(1000);});) erfolgt über einen Thread im Thread-Pool der Anwendung. Da dieser Aufruf versucht, die Benutzeroberfläche von einem nicht-UI-Thread zu aktualisieren, wird durch die Anweisung einInvalidOperationException ausgelöst
WPF und Store-Anwendungen
Hinweis
In Store Phone-Anwendungen wird ein Exception anstatt der spezifischeren InvalidOperationException ausgelöst.
Ausnahmemeldungen:
WPF-Anwendungen |
Zusätzliche Informationen: Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da ein anderer Thread es besitzt. |
Store-Apps |
Weitere Informationen: Die Anwendung rief eine Schnittstelle auf, die für einen anderen Thread der Anwendung aufgerufen wurde. (Ausnahme von HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)) |
private async void ThreadsExampleBtn_Click(object sender, RoutedEventArgs e)
{
TextBox1.Text = String.Empty;
TextBox1.Text = "Simulating work on UI thread.\n";
DoSomeWork(20);
TextBox1.Text += "Simulating work on non-UI thread.\n";
await Task.Run(() => DoSomeWork(1000));
TextBox1.Text += "ThreadsExampleBtn_Click completes. ";
}
private void DoSomeWork(int msOfWork)
{
// simulate work
var endTime = DateTime.Now.AddMilliseconds(msOfWork);
while (DateTime.Now < endTime)
{
// spin
};
// report completion
var msg = String.Format("Some work completed in {0} ms on UI thread. \n", msOfWork);
TextBox1.Text += msg;
}
Windows Forms-Anwendungen
Ausnahmemeldung:
- Weitere Informationen: threadübergreifender Vorgang ungültig: Steuerelement "TextBox1" von einem anderen Thread als dem erstellten Thread aufgerufen.
private async void ThreadsExampleBtn_Click(object sender, EventArgs e)
{
TextBox1.Text = String.Empty;
var tbLinesList = new List<string>() {"Simulating work on UI thread."};
TextBox1.Lines = tbLinesList.ToArray();
DoSomeWork(20, tbLinesList);
tbLinesList.Add("Simulating work on non-UI thread.");
TextBox1.Lines = tbLinesList.ToArray();
await Task.Run(() => DoSomeWork(1000, tbLinesList));
tbLinesList.Add("ThreadsExampleBtn_Click completes.");
TextBox1.Lines = tbLinesList.ToArray();
}
private void DoSomeWork(int msOfWork, List<string> tbLinesList)
{
// simulate work
var endTime = DateTime.Now.AddMilliseconds(msOfWork);
while (DateTime.Now < endTime) { };
{
// spin
};
// report completion
var msg = String.Format("Some work completed in {0} ms on UI thread. \n", msOfWork);
tbLinesList.Add(msg);
TextBox1.Lines = tbLinesList.ToArray();
}
In diesem ArtikelIn diesem Abschnitt
Vermeiden von InvalidOperationExceptions in nicht-UI-Threads
Windows-Benutzeroberflächen-Frameworks implementieren ein Dispatcher-Muster, das eine Methode umfasst, mit der überprüft werden kann, ob ein Aufruf an ein Mitglied eines Benutzeroberflächenelements auf dem UI-Thread ausgeführt wird, und andere Methoden, um den Anruf an den UI-Thread zu planen.
WPF-Anwendungen
In WPF-Anwendungen verwenden Sie eine der Dispatcher.Invoke-Methoden, um einen Delegaten auf dem UI-Thread auszuführen. Verwenden Sie bei Bedarf die Dispatcher.CheckAccess-Methode, um festzulegen, ob eine Methode in einem nicht-UI-Thread ausgeführt wird oder nicht.
private void DoSomeWork(int msOfWork)
{
var endTime = DateTime.Now.AddMilliseconds(msOfWork);
while (DateTime.Now < endTime)
{
// spin
};
// report completion
var msgFormat = "Some work completed in {0} ms on {1}UI thread.\n";
var msg = String.Empty;
if (TextBox1.Dispatcher.CheckAccess())
{
msg = String.Format(msgFormat, msOfWork, String.Empty);
TextBox1.Text += msg;
}
else
{
msg = String.Format(msgFormat, msOfWork, "non-");
Action act = ()=> {TextBox1.Text += msg;};
TextBox1.Dispatcher.Invoke(act);
}
}
Windows Forms-Anwendungen
In Windows Forms-Anwendungen verwenden die Control.Invoke-Methode, um einen Delegaten auszuführen, der den UI-Thread aktualisiert. Verwenden Sie bei Bedarf die Control.InvokeRequired-Methode, um festzulegen, ob eine Methode in einem nicht-UI-Thread ausgeführt wird oder nicht.
private void DoSomeWork(int msOfWork, List<string> tbLinesList)
{
// simulate work
var endTime = DateTime.Now.AddMilliseconds(msOfWork);
while (DateTime.Now < endTime)
{
// spin
};
// report completion
var msgFormat = "Some work completed in {0} ms on {1}UI thread.\n";
var msg = String.Empty;
if (TextBox1.InvokeRequired)
{
msg = String.Format(msgFormat, msOfWork, "non-");
tbLinesList.Add(msg);
Action act = () => TextBox1.Lines = tbLinesList.ToArray();
TextBox1.Invoke( act );
}
else
{
msg = String.Format(msgFormat, msOfWork, String.Empty);
tbLinesList.Add(msg);
TextBox1.Lines = tbLinesList.ToArray();
}
}
Store-Apps
In Windows Forms-Anwendungen verwenden Sie die CoreDispatcher.RunAsync-Methode, um einen Delegaten auszuführen, der den UI-Thread aktualisiert. Verwenden Sie bei Bedarf die HasThreadAccess-Methode, um festzulegen, ob eine Methode in einem nicht-UI-Thread ausgeführt wird oder nicht.
private void DoSomeWork(int msOfWork)
{
// simulate work
var endTime = DateTime.Now.AddMilliseconds(msOfWork);
while (DateTime.Now < endTime)
{
// spin
};
// report completion
var msgFormat = "Some work completed in {0} ms on {1}UI thread.\n";
var msg = String.Empty;
if (TextBox1.Dispatcher.HasThreadAccess)
{
msg = String.Format(msgFormat, msOfWork, String.Empty);
TextBox1.Text += msg;
}
else
{
msg = String.Format(msgFormat, msOfWork, "non-");
TextBox1.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
()=> {TextBox1.Text += msg;});
}
}
In diesem ArtikelIn diesem Abschnitt
Eine Anweisung in einer Foreach (For Each in Visual Basic)-Block ändert die Sammlung, die sie durchläuft
Verursacht eine InvalidOperationException mit foreach | Vermeidet InvalidOperationExceptions in Schleifen
Eine foreach-Anweisung (For Each in Visual Basic) wiederholt eine Gruppe von eingebetteten Anweisungen für jedes Element in einem Array oder einer Auflistung, die die IEnumerable oder IEnumerable-Schnittstelle implementiert. Die foreach-Anweisung wird zum Durchlaufen der Auflistung zum Lesen und Ändern der Elemente, aber nicht zum Hinzufügen oder Entfernen von Elementen aus der Auflistung verwendet. Ein InvalidOperationException wird ausgelöst, wenn Sie Elemente aus der Auflistung in einer Foreach-Anweisung hinzufügen oder daraus entfernen.
Verursacht eine InvalidOperationException mit foreach
In diesem Beispiel wird eine InvalidOperationException ausgelöst, wenn die numList.Add(5);-Anweisung versucht, die Liste im Foreach-Block zu ändern.
Ausnahmemeldung:
- Zusätzliche Informationen: Die Auflistung wurde geändert; der Enumerationsvorgang kann nicht ausgeführt werden.
private void AddElementsToAList()
{
var numList = new List<int>() { 1, 2, 3, 4 };
foreach (var num in numList)
{
if (num == 2)
{
numList.Add(5);
}
}
// Display list elements
foreach (var num in numList)
{
Console.Write("{0} ", num);
}
}
In diesem ArtikelIn diesem Abschnitt
Vermeidet InvalidOperationExceptions in Schleifen
Wichtig
Das Hinzufügen oder Entfernen von Elementen zu einer Liste während Sie die Sammlung durchlaufen können unbeabsichtigte und schwer vorhersagbare Nebenwirkungen haben.Wenn möglich, sollten Sie den Vorgang außerhalb der Iteration verschieben.
private void AddElementsToAList ()
{
var numList = new List<int>() { 1, 2, 3, 4 };
var numberOf2s = 0;
foreach (var num in numList)
{
if (num == 2)
{
numberOf2s++;
}
}
for (var i = 0; i < numberOf2s; i++ )
{
numList.Add(5);
}
// Display list elements
foreach (var num in numList)
{
Console.Write("{0} ", num);
}
}
Falls Ihre Situation erfordet, dass Sie Elemente zu einer Liste hinzufügen oder daraus entfernen, während Sie eine Liste durchlaufen, verwenden Sie eine Schleife für (für in Visual Basic):
private void AddElementsToAList ()
{
var numList = new List<int>() { 1, 2, 3, 4 };
for (var i = 0; i < numList.Count; i++)
{
if (numList[i] == 2)
{
numList.Add(5);
}
}
// Display list elements
foreach (var num in numList)
{
Console.Write("{0} ", num);
}
}
In diesem ArtikelIn diesem Abschnitt
Ein Typ Nullable < T >, der null ist, wird in T umgewandelt.
Verursachen einer InvalidOperationException mit einer ungültigen Umwandlung | Vermeiden von InvalidOperationException aus eine ungültigen Umwandlung
Wenn Sie eine StrukturNullable auslösen, die in dem zugrunde liegenden Typ null (Nothing in Visual Basic) ist, wird eine InvalidOperationException-Ausnahme ausgelöst.
Verursachen einer InvalidOperationException mit einer ungültigen Umwandlung
Bei dieser Methode wird eine InvalidOperationException ausgelöst, wenn die Select-Methode ein null-Element des DbQueryResults in int umgewandelt
Ausnahmemeldung:
- Weitere Informationen: Auf null festlegbares Objekt muss einen Wert haben.
private void MapQueryResults()
{
var dbQueryResults = new int?[] { 1, 2, null, 4 };
var ormMap = dbQueryResults.Select(nullableInt => (int)nullableInt);
//display map list
foreach (var num in ormMap)
{
Console.Write("{0} ", num);
}
Console.WriteLine();
}
In diesem ArtikelIn diesem Abschnitt
Vermeiden von InvalidOperationException aus eine ungültigen Umwandlung
Um InvalidOperationException zu vermeiden:
Verwenden Sie die Nullable.HasValue-Eigenschaft, um nur die Elemente auszuwählen, die nicht null sind.
Verwenden Sie eine der überladenen Nullable.GetValueOrDefault Methoden, um einen Standardwert für ein null-Element anzugeben.
Nullable < T >.HasValue Beispiel
private void MapQueryResults()
{
var dbQueryResults = new int?[] { 1, 2, null, 4 };
var ormMap = dbQueryResults
.Where(nulllableInt => nulllableInt.HasValue)
.Select(num => (int)num);
//display map list
foreach (var num in ormMap)
{
Console.Write("{0} ", num);
}
Console.WriteLine();
// handle nulls
Console.WriteLine("{0} nulls encountered in dbQueryResults",
dbQueryResults.Where(nullableInt => !nullableInt.HasValue).Count());
}
Nullable < T >.GetValueOrDefault Beispiel
In diesem Beispiel verwenden wir GetValueOrDefault(UTP) zur Angabe eines Standardwertes, der außerhalb der von dbQueryResults zurückgegebenen erwarteten Werten liegt.
private void MapQueryResults()
{
var dbQueryResults = new int?[] { 1, 2, null, 4 };
var nullFlag = int.MinValue;
var ormMap = dbQueryResults.Select(nullableInt => nullableInt.GetValueOrDefault(nullFlag));
// handle nulls
Console.WriteLine("'{0}' indicates a null database value.", nullFlag);
foreach (var num in ormMap)
{
Console.Write("{0} ", num);
}
Console.WriteLine();
}
In diesem ArtikelIn diesem Abschnitt
Eine System.Linq.Enumerable-Methode wird für eine leere Auflistung aufgerufen.
Die Enumerable MethodenAggregate, Average, Last, Max, Min, First, Single und SingleOrDefault führen Operationen für eine Sequenz durch und geben ein Einzelergebnis zurück.
Einige Überladungen dieser Methoden lösen eine InvalidOperationException Ausnahme aus, wenn die Sequenz leer ist (andere Überladungen gebennull (Nothing in Visual Basic) zurück. SingleOrDefaultlöst außerdem InvalidOperationException aus, wenn die Sequenz mehr als ein Element enthält.
Tipp
Die meisten der Enumerable in diesem Abschnitt diskutierten Methoden sind überladen.Achten Sie darauf, dass Sie das Verhalten der Überladung verstehen, die Sie auswählen.
Ausnahmemeldungen:
Summe, Durchschnitt, Letzte, Max und Min Methoden | First und FirstOrDefault-Methoden | Single- und SingleOrDefault-Methoden
Summe, Durchschnitt, Letzte, Max und Min Methoden
- Weitere Informationen: Sequenz enthält keine Elemente
Verursacht eine InvalidOperationException mit Durchschnitt
In diesem Beispiel löst die folgende Methode eine InvalidOperationException aus, wenn sie die Average-Methode aufruft, da der Ausdruck Linq eine Sequenz zurückgibt, die keine Elemente enthält, die größer sind als 4.
private void FindAverageOfNumbersGreaterThan4()
{
var dbQueryResults = new[] { 1, 2, 3, 4 };
var avg = dbQueryResults.Where(num => num > 4).Average();
Console.WriteLine("The average value numbers greater than 4 in the returned records is {0}", avg);
}
Wenn Sie eine dieser Methoden verwenden, ohne eine Überprüfung auf eine leere Sequenz durchzuführen, gehen Sie implizit davon aus, dass die Sequenz nicht leer ist und eine leere Sequenz ein unerwartetes Ereignis ist. Das Abfangen oder Auslösen der Ausnahme ist geeignet, wenn Sie davon ausgehen, dass die Sequenz nicht leer ist.
Vermeiden Sie eine InvalidOperationException, die von einer leeren Sequenz zurückgeführt wird.
Verwenden Sie eine der Enumerable.Any Methoden, um zu überprüfen, ob die Sequenz leer ist.
Tipp
Mit Any kann die Prüfleistung verbessert werden, wenn die Sequenz, die durchschnittliche Sequenz möglicherweise eine große Anzahl von Elementen enthält oder wenn die Operation, die die Sequenz generiert, teuer ist.
private void FindAverageOfNumbersGreaterThan4()
{
var dbQueryResults = new[] { 1, 2, 3, 4 };
var moreThan4 = dbQueryResults.Where(num => num > 4);
if(moreThan4.Any())
{
var msgFormat = "The average value numbers greater than 4 in the returned records is {0}";
Console.WriteLine(msgFormat, moreThan4.Average());
}
else
{
// handle empty collection
Console.WriteLine("There are no values greater than 4 in the ecords.");
}
}
In diesem ArtikelIn diesem Abschnitt
First und FirstOrDefault-Methoden
First gibt das erste Element in einer Sequenz zurück oder löst eine InvalidOperationException aus, wenn die Sequenz leer ist. Sie erreichen die FirstOrDefault-Methode anstelle von First zum Zurückgeben eines angegebenen Werts oder Standardwerts, statt die Ausnahme auszulösen.
Hinweis
Im .NET Framework verfügen Typen über ein Konzept von Standardwerten.Für jeden Referenztyp ist der Standardwert beispielsweise null, und für einen Integertyp ist er 0 (null).Siehe Tabelle für Standardwerte (C#-Referenz).
Auslösen einer InvalidOperationException mit First
Die First ist eine Methode der Leistungsoptimierung, die das erste Element in einer Sequenz zurückgeben wird, die eine angegebene Bedingung erfüllt. Wenn ein Element, das die Bedingung nicht erfüllt, nicht gefunden wird, lösen die Methoden eine InvalidOperationException Ausnahme aus.
In diesem Beispiel löst die First-Methode eine Ausnahme aus, da dbQueryResults kein Element enthält, das größer als 4 ist.
Ausnahmemeldung:
- Zusätzliche Informationen: Die Sequenz enthält kein übereinstimmendes Element
private void FindANumbersGreaterThan4()
{
var dbQueryResults = new[] { 1, 2, 3, 4 };
var firstNum = dbQueryResults.First(n=> n > 4);
var msgFormat = "{0} is an element of dbQueryResults that is greater than 4";
Console.WriteLine(msgFormat, firstNum);
}
Vermeiden einer Ausnahme mit "FirstOrDefault"
Verwenden Sie eine der FirstOrDefault-Methoden anstelle von First, um zu prüfen, ob die firstNum Sequenz mindestens ein Element enthält. Wenn bei der Abfrage kein Element gefunden wird, das die Bedingung erfüllt, gibt sie einen angegebenen oder Standardwert zurück. Sie können den zurückgegebenen Wert überprüfen, um festzustellen, ob alle Elemente gefunden werden.
Hinweis
Mit kann FirstOrDefault schwieriger zu implementieren sein, wenn der Standardwert des Typs ein gültiges Element in der Sequenz ist.
private void FindANumbersGreaterThan4()
{
var dbQueryResults = new[] { 1, 2, 3, 4 };
// default(object) == null
var firstNum = dbQueryResults.FirstOrDefault(n => n > 4);
if (firstNum != 0)
{
var msgFormat = "{0} is an element of dbQueryResults that is greater than 4";
Console.WriteLine(msgFormat, firstNum);
}
else
{
// handle default case
Console.WriteLine("No element of dbQueryResults is greater than 4.");
}
}
In diesem ArtikelIn diesem Abschnitt
Single- und SingleOrDefault-Methoden
Die Enumerable.Single-Methode gibt das einzige Element einer Sequenz oder das einzige Element einer Sequenz, das einen angegebenen Test besteht, zurück.
Wenn keine Elemente in der Sequenz vorhanden sind, oder wenn mehr als ein Element in der Sequenz vorhanden ist, löst die Methode eine InvalidOperationException Ausnahme aus.
Sie können SingleOrDefault zum Zurückgeben eines angegebenen Werts oder Standardwerts verwenden, anstatt die Ausnahme auszulösen, wenn die Sequenz keine Elemente enthält. Allerdings löst SingleOrDefault immer noch ein InvalidOperationException aus, wenn die Sequenz mehr als ein Element enthält, das das Auswahlprädikat erfüllt.
Hinweis
Im .NET Framework verfügen Typen über ein Konzept von Standardwerten.Für jeden Referenztyp ist der Standardwert beispielsweise null, und für einen Integertyp ist er 0 (null).Siehe Tabelle für Standardwerte (C#-Referenz).
Auslösen von InvalidOperationExceptions mit
In diesem Beispiel löst singleObject eine InvalidOperationException aus, da dbQueryResults kein Element enthält, das größer als 4 ist.
Ausnahmemeldung:
- Zusätzliche Informationen: Die Sequenz enthält kein übereinstimmendes Element
private void FindTheOnlyNumberGreaterThan4()
{
var dbQueryResults = new[] { (object)1, (object)2, (object)3, (object)4 };
var singleObject = dbQueryResults.Single(obj => (int)obj > 4);
// display results
var msgFormat = "{0} is the only element of dbQueryResults that is greater than 4";
Console.WriteLine(msgFormat, singleObject);
}
Auslösen von InvalidOperationExceptions mit Single oder SingleOrDefault
In diesem Beispiel löst singleObject eine InvalidOperationException aus, da dbQueryResults mehr als ein Element enthält, das größer ist als 2.
Ausnahmemeldung:
- Zusätzliche Informationen: die Sequenz enthält mehrere übereinstimmende Elemente
private void FindTheOnlyNumberGreaterThan2()
{
var dbQueryResults = new[] { (object)1, (object)2, (object)3, (object)4 };
var singleObject = dbQueryResults.SingleOrDefault(obj => (int)obj > 2);
if (singleObject != null)
{
var msgFormat = "{0} is the only element of dbQueryResults that is greater than 2";
Console.WriteLine(msgFormat, singleObject);
}
else
{
// handle empty collection
Console.WriteLine("No element of dbQueryResults is greater than 2.");
}
}
Vermeiden von InvalidOperationExceptions mit Single
Single und SingleOrDefault dienen auch als Dokumentation für Ihre Absichten. Single stark setzt voraus, dass Sie erwarten, dass nur ein Ergebnis aus dem Zustand zurückgegeben wird. SingleOrDefault deklariert, dass Sie ein oder null aber nicht mehr Ergebnisse erwarten. Wenn diese Bedingungen nicht zutreffen, ist das Auslösen und Abfangen der InvalidOperationException geeignet. Wenn Sie jedoch erwarten, dass ungültige Bedingungen häufig auftreten, sollten Sie mit anderen Enumerable-Methoden, z. B. First oder Where die Ergebnisse generieren.
Während der Entwicklung können Sie mit einer der Assert-Methoden Ihre Annahmen überprüfen. In diesem Beispiel bewirkt der hervorgehobene Code, dass der Debugger bricht, und zeigt das Dialogfeld Assert während der Entwicklung an. Die Assertion ist im Versions-Code entfernt, und jede Single wird ausgelöst, wenn die Ergebnisse ungültig sind.
Hinweis
Mit Take``1 und der Konfiguration seines count-Parameters auf 2 wird die zurückgegebene Sequenz auf höchstens zwei Elemente beschränkt.Diese Reihenfolge gilt auch für alle Fälle, die Sie benötigen, um (0, 1 und mehr als 1 Elemente) zu überprüfen, und kann die Prüfleistung verbessern, wenn die Sequenz eine große Anzahl von Elementen enthält oder wenn die Operation, die die Sequenz generiert, teuer ist.
private void FindTheOnlyNumberGreaterThan4()
{
var dbQueryResults = new[] { (object)1, (object)2, (object)3, (object)4 };
var moreThan4 = dbQueryResults.Where(obj => (int)obj > 4).Take(2);
System.Diagnostics.Debug.Assert(moreThan4.Count() == 1,
String.Format("moreThan4.Count() == 1; Actual count: {0}", moreThan4.Count()));
// do not handle exceptions in release code
Console.WriteLine("{0} is the only element of dbQueryResults that is greater than 4",
moreThan4.Single());
}
Wenn Sie die Ausnahme verhindern, aber immernoch die ungültigen Zustände im Versions-Code behandeln möchten, können Sie das oben beschriebene Verfahren ändern. In diesem Beispiel reagiert die Methode auf die Anzahl von zurückgegebenen Elementen moreThan2 in der Switch-Anweisung.
private void FindTheOnlyNumberGreaterThan2()
{
var dbQueryResults = new[] { (object)1, (object)2, (object)3, (object)4 };
var moreThan2 = dbQueryResults.TakeWhile(obj => (int)obj > 2).Take(2);
switch(moreThan2.Count())
{
case 1:
// success
var msgFormat = "{0} is the only element of dbQueryResults that is greater than 2";
Console.WriteLine(msgFormat, moreThan2.Single());
break;
case 0:
// handle empty collection
Console.WriteLine("No element of the dbQueryResults are greater than 4.");
break;
default: // count > 1
// handle more than one element
Console.WriteLine("More than one element of dbQueryResults is greater than 4");
break;
}
}
In diesem ArtikelIn diesem Abschnitt
Verwandte Artikel
Entwurfsrichtlinien für Ausnahmen (.NET Framework-Entwurfsrichtlinien)
Behandeln und Auslösen von Ausnahmen (.NET Framework-Anwendungsgrundlagen)
Vorgehensweise:Empfangen von Ausnahmebenachrichtigungen (.NET Framework-Entwicklungsleitfaden)
Ausnahmen in verwalteten Threads (.NET Framework-Entwicklungsleitfaden)
Ausnahmen und Ausnahmebehandlung (C#-Programmierhandbuch)
Ausnahmebehandlungsanweisungen (C#-Referenz)
Try...Catch...Finally-Anweisung (Visual Basic)
Ausnahmebehandlung (Task Parallel Library)
Ausnahmebehandlung (Debugging)
Exemplare Vorgehensweise: Behandeln einer Parallelitätsausnahme (Datenzugriff in Visual Studio)
Behandeln von Ausnahmen in Netzwerk-Apps (XAML) (Windows)
In diesem Artikel