Udostępnij za pośrednictwem


Rozwiązywanie problemów z wyjątkami: System.InvalidOperationException

InvalidOperationException Jest generowany, gdy metoda obiektu jest wywoływane, gdy stan obiektu nie może obsługiwać wywołania metody.Wyjątek jest również metodę próba manipulowania interfejsu użytkownika z wątku, który nie głównym lub wątku interfejsu użytkownika.

Ważna uwagaWażne

Ponieważ InvalidOperationExceptions może zostać wygenerowany w różnych typów okoliczności, należy przeczytać i zrozumieć Message która jest wyświetlana w oknie Asystenta wyjątku.

W tym artykule

Metodę uruchomiony w wątku bez interfejsu użytkownika aktualizuje interfejsu użytkownika

instrukcji w bloku foreach (dla każdego w języku Visual Basic) zmienia kolekcji, jest on Iterowanie

wartości null < T >, który ma wartość null jest rzutowane na T

System.Linq.Enumerable metoda jest wywoływana w pustej kolekcji

powiązane artykuły

Przykłady kodu, w tym artykule wyświetlona jak niektóre typowe InvalidOperationException wyjątków może wystąpić w aplikacji.Jak obsługiwać problemy zależy od konkretnej sytuacji.Jeśli wyjątek krytyczny działanie aplikacji, należy użyć ... Spróbuj catch (Spróbuj... CATCH w języku Visual Basic) konstrukcji do przechwytywania wyjątek i Wyczyść stan aplikacji przed zamknięciem.Ale inne InvalidOperationExceptions może oczekiwać i unikać.Metoda poprawione przykładach przedstawiono niektóre z tych metod.

Metoda działa na wątek bez interfejsu użytkownika aktualizuje interfejsu użytkownika

Powoduje InvalidOperationException z aktualizacją interfejsu użytkownika z wątku bez interfejsu użytkownika | Unikanie InvalidOperationExceptions w wątkach bez interfejsu użytkownika

Większość struktur aplikacji .NET GUI (graficzny interfejs użytkownika), takie jak formularze systemu Windows i Windows Presentation Foundation (WPF), umożliwiają dostęp do obiektów GUI tylko z wątku, który tworzy i zarządza interfejsu użytkownika ( główne lub interfejsu użytkownika wątek).InvalidOperationException Jest generowany, gdy użytkownik próbuje uzyskać dostęp do elementu interfejsu użytkownika z wątku, który nie jest wątku interfejsu użytkownika.

Powoduje InvalidOperationException z aktualizacją interfejsu użytkownika z wątku bez interfejsu użytkownika

[!UWAGA]

W poniższych przykładach użyto Wzorzec asynchroniczny oparty na zadaniach (TAP) do utworzenia wątki bez interfejsu użytkownika.Jednak przykłady dotyczą również wszystkich .NET Wzorce programowania asynchronicznego.

W tym przykładzie ThreadsExampleBtn_Click wywołań obsługi zdarzeń DoSomeWork metody dwa razy.Pierwsze wywołanie do metody (DoSomeWork(20); działa sychronously i zakończy się powodzeniem.Drugie wywołanie, ale (Task.Run( () => { DoSomeWork(1000);});) jest uruchamiana na wątek w aplikacji puli wątków.Ponieważ to wywołanie podejmie próbę zaktualizowania interfejsu użytkownika z wątku bez interfejsu użytkownika, instrukcja zgłasza wyjątek, InvalidOperationException

Aplikacje WPF i magazynu

[!UWAGA]

W aplikacjach sklepu Telefon Exception jest generowany, a nie więcej określonych InvalidOperationException.

Komunikaty o wyjątku:

Aplikacje WPF

Informacje dodatkowe: wątek wywołującego nie może uzyskać dostępu tego obiektu, ponieważ inny wątek jest jej właścicielem.

Aplikacje Sklepu

Informacje dodatkowe: aplikacja nazwę interfejs, który został skierowany na inny wątek.(Wyjątek od 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 aplikacji

Komunikat wyjątku:

  • Informacje dodatkowe: Nieprawidłowa operacja wątku Cross: formant "Poletekstowe1" dostępne z wątku innego niż wątek został utworzony na.
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();
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Unikanie InvalidOperationExceptions w wątkach bez interfejsu użytkownika

Implementacji interfejsu użytkownika Windows struktur dyspozytora wzorzec, który zawiera metodę, aby sprawdzić, czy po wywołaniu członkiem elementu interfejsu użytkownika jest wykonywana w wątku interfejsu użytkownika i innych metod, aby zaplanować połączenie w wątku interfejsu użytkownika.

Aplikacje WPF

W aplikacjach WPF, należy użyć jednej z Dispatcher.Invoke metody służące do excecute delegata w wątku interfejsu użytkownika.Jeśli to konieczne, użyj Dispatcher.CheckAccess metodę w celu określenia, czy metoda jest uruchomiona na wątek bez interfejsu użytkownika.

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 aplikacji

W aplikacjach formularz systemu Windows, należy użyć Control.Invoke metodę w celu excecute delegata, która aktualizuje wątku interfejsu użytkownika.Jeśli to konieczne, użyj Control.InvokeRequired Właściwości w celu określenia, czy metoda jest uruchomiona na wątek bez interfejsu użytkownika.

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();
    }
}

Aplikacje Sklepu

W aplikacjach ze sklepu, użyj CoreDispatcher.RunAsync metodę w celu excecute delegata, która aktualizuje wątku interfejsu użytkownika.Jeśli to konieczne, użyj HasThreadAccess Właściwości w celu określenia, czy metoda jest uruchomiona na wątek bez interfejsu użytkownika.

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;});
    }
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Kolekcji, który jest on Iterowanie zmienia instrukcji w bloku foreach (dla każdego w języku Visual Basic)

Powoduje InvalidOperationException z foreach | Unikanie InvalidOperationExceptions w pętli

Element foreach instrukcji (dla każdego w języku Visual Basic) powtarza grupy stwierdzeń, embedded dla poszczególnych elementów w tablicy lub kolekcji, który implementuje IEnumerable lub IEnumerable interfejsu.foreach Instrukcja jest używana do iteracji w kolekcji do odczytania i modyfikowania elementów, ale nie można dodać lub usunąć elementy z kolekcji.InvalidOperationException Zgłaszany w przypadku można dodać lub usunąć elementy z kolekcji źródłowej w instrukcji foreach.

Powoduje InvalidOperationException z foreach

W tym przykładzie InvalidOperationException jest generowany, gdy numList.Add(5); próbuje zmodyfikować listę w bloku foreach instrukcji.

Komunikat wyjątku:

  • Informacje dodatkowe: kolekcja została zmodyfikowana; Nie można wykonać operacji wyliczania.
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);
    }
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Unikanie InvalidOperationExceptions w pętli

Ważna uwagaWażne

Dodawanie lub usuwanie elementów do listy, gdy są interating w kolekcji może mieć niepożądanych i trudne do prognozowania efekty uboczne.Jeśli to możliwe należy przenosić operacji poza iteracji.

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);
    }
}

Jeśli danej sytuacji, musisz dodać lub usunąć elementy z listy podczas iteracji w kolekcji, użyj dla (dla w języku Visual Basic) Pętla:

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);
    }
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Nullable &lt; T &gt;, który ma wartość null jest rzutowane na T

Powoduje InvalidOperationException z nieprawidłową rzutowania | Unikanie InvalidOperationException z nieprawidłowych rzutowania

Jeśli użytkownik rzutowania Nullable struktury, który jest null (Nothing w języku Visual Basic) do jej źródłowy typ InvalidOperationException wyjątku.

Powoduje InvalidOperationException z nieprawidłową rzutowania

W tej metodzie InvalidOperationException jest generowany, gdy metody Select rzutuje element null elementu dbQueryResults, aby liczba całkowita.

Komunikat wyjątku:

  • Informacje dodatkowe: obiekt wartości null musi mieć wartość.
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();
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Unikanie InvalidOperationException z nieprawidłowych rzutowania

Aby uniknąć InvalidOperationException:

  • Użyj Nullable.HasValue Właściwości można wybrać tylko te elementy, które nie mają wartości null.

  • Użyj jednego z przeciążenia Nullable.GetValueOrDefault metody udostępniające wartość domyślną dla elementu o wartości null.

Wartość null jest dozwolona < T >.Przykład HasValue

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());
}

Wartość null jest dozwolona < T >.Przykład GetValueOrDefault

W tym przykładzie korzystamy z GetValueOrDefault(UTP) można określić wartość domyślną, która znajduje się poza oczekiwanych wartości zwracane przez dbQueryResults.

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();
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Metoda System.Linq.Enumerable jest wywoływana w pustej kolekcji.

Enumerable Metody Aggregate, Average, Last, Max, Min, First, Single, i SingleOrDefault wykonywania operacji na sekwencję i zwracają jeden wynik.

Wyjątek przeciążenia niektóre z tych metod InvalidOperationException wyjątek podczas sekwencji jest pusty (inne przeciążanie zwrotu null (Nothing w języku Visual Basic).SingleOrDefault Ponadto zgłasza wyjątek InvalidOperationException podczas sekwencji zawiera więcej niż jeden element.

PoradaPorada

Większość Enumerable disussed metody w tej sekcji są przeciążone.Upewnij się, że zrozumieć zachowanie przeciążenia wybranego przez użytkownika.

Komunikaty o wyjątku:

Wartość zagregowaną, metody średniej, Last, Max i Min | Pierwszy i metody FirstOrDefault | Pojedynczy i metody SingleOrDefault

Wartość zagregowaną, metody średniej, Last, Max i Min

  • Informacje dodatkowe: sekwencji nie zawiera żadnych elementów

Powoduje InvalidOperationException o średniej

W tym przykładzie metoda następujące zgłasza InvalidOperationException podczas wywołania Average Metoda, ponieważ wyrażenie Linq zwraca sekwencję zawierającą nie elementy, które są większe niż 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);
}

Korzystając z jednej z tych metod bez sprawdzania sekwencji puste, są niejawnie zakładając sekwencji nie jest pusta i że pusty sekwencji jest nieoczekiwany wystąpienie.Przechwytywaniem lub zwracania wyjątku jest odpowiedni w przypadku założyć, że sekwencji będzie pusty.

Unikanie InvalidOperationException spowodowany pusty sekwencji

Użyj jednego z Enumerable.Any metody do sprawdzenia, czy sekwencja jest pusty.

PoradaPorada

Przy użyciu Any może zwiększyć wydajność sprawdzania, czy sekwencja średnia może zawierać dużą liczbę elementów lub jeśli operacji, który generuje sekwencji jest kosztowna.

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.");
    }
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Pierwszy i metody FirstOrDefault

First Zwraca pierwszy element w sekwencji lub zgłasza wyjątek InvalidOperationException Jeśli sekwencji jest pusta.Można wywołać metodę FirstOrDefault zamiast metody First Aby zwracać określoną lub domyślna wartość zamiast zgłaszania wyjątku.

[!UWAGA]

W programie .NET Framework typy mają koncepcją wartości domyślne.Na przykład dla jakiegokolwiek odniesienia wartość domyślna typu ma wartość null, a dla typu Liczba całkowita jest zero.Zobacz Tabela wartości domyślnych (odwołanie w C#)

Powoduje InvalidOperationException z pierwszej

First Jest metoda optymalizacji, która zwraca pierwszy element w sekwencji spełniających kryteria określonego warunku.Jeśli element spełniającą ten warunek nie zostanie odnaleziony, wyjątek metody InvalidOperationException wyjątku.

W tym przykładzie First Metoda zgłasza wyjątek, ponieważ dbQueryResults nie zawiera element, który jest większy niż 4.

Komunikat wyjątku:

  • Informacje dodatkowe: nie zawiera sekwencji
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);

}

Unikanie wyjątek z FirstOrDefault

Można użyć jednej FirstOrDefault metody zamiast właściwości First musi sprawdzić, czy firstNum Sekwencja zawiera co najmniej jeden element.Jeśli zapytanie nie może znaleźć elementu spełniającą ten warunek, zwraca określoną lub wartość domyślna.Można sprawdzić zwracanej wartości, aby określić, jeśli znaleziono żadnych elementów.

[!UWAGA]

Przy użyciu FirstOrDefault może być trudniejsze do zaimplementowania, jeśli wartość domyślna typu jest prawidłowym elementem w sekwencji.

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.");
    }
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Pojedynczy i metody SingleOrDefault

Enumerable.Single Metody zwracają jedynym elementem sekwencji lub jedynym elementem dopasowaną test określonej sekwencji.

Jeśli nie ma żadnych elementów w sekwencji, lub więcej niż jeden element w t on sekwencjonowania, generuje metnod InvalidOperationException wyjątku.

Można użyć SingleOrDefault Aby zwracać określoną lub domyślna wartość zamiast zgłaszania wyjątek podczas sekwencji nie zawiera żadnych elementów.Jednak SingleOrDefault wciąż zgłasza wyjątek InvalidOperationException podczas sekwencji zawiera więcej niż jeden element, który odpowiada predykat zaznaczenia.

[!UWAGA]

W programie .NET Framework typy mają koncepcją wartości domyślne.Na przykład dla jakiegokolwiek odniesienia wartość domyślna typu ma wartość null, a dla typu Liczba całkowita jest zero.Zobacz Tabela wartości domyślnych (odwołanie w C#)

Powoduje InvalidOperationExceptions z pojedynczym

W tym przykładzie singleObject zgłasza wyjątek InvalidOperationException ponieważ dbQueryResults nie zawiera elementu większą niż 4.

Komunikat wyjątku:

  • Informacje dodatkowe: nie zawiera sekwencji
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);
}

Powoduje InvalidOperationExceptions z pojedynczym lub SingleOrDefault

W tym przykładzie singleObject zgłasza wyjątek InvalidOperationException ponieważ dbQueryResults zawiera więcej niż jeden element większa niż 2.

Komunikat wyjątku:

  • Informacje dodatkowe: sekwencja zawiera więcej niż jeden element zgodnych
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.");
    }
}

Unikanie InvalidOperationExceptions z pojedynczym

Przy użyciu Single i SingleOrDefault stanowi również dokumentację zamiaru.Single Zdecydowanie oznacza, że oczekują jeden i tylko jeden wynik ma zostać zwrócona z warunek.SingleOrDefault oświadcza, że oczekuje jednej lub bez wyników, ale nie więcej.Jeśli te warunki są nieprawidłowe, zgłaszania lub przechwytywaniem InvalidOperationException jest odpowiedni.Jednakże, Jeśli przypuszczasz, że nieprawidłowe warunki będzie miało miejsce z niektórych częstotliwością, należy rozważyć użycie innych Enumerable metod, takich jak First lub Where, aby wygenerować wyniki.

Podczas tworzenia aplikacji, można użyć jednej z Assert metody do sprawdzenia swojego założenia.W tym przykładzie zaznaczony kod powoduje, że debuger rozbić i wyświetla okno dialogowe potwierdzenia podczas tworzenia aplikacji.Potwierdzenia zostanie usunięta w wersji kodu oraz wszelkie Single zgłasza wyjątek, jeśli wyniki są nieprawidłowe.

[!UWAGA]

Przy użyciu Take``1 i ustawienie jej count parametr 2 ogranicza zwracany sekwencji na maksymalnie dwa elementy.Ta sekwencja obejmuje wszystkie przypadki, które są potrzebne do sprawdzenia (0, 1 i elementy więcej niż 1) i może zwiększyć wydajność sprawdzanie sekwencji może zawierać dużą liczbę elementów lub operacji, który generuje sekwencji jest kosztowna.

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());
}

Jeśli chcesz uniknąć wyjątek, ale nadal obsługiwać nieprawidłowe stany w kodzie wersji, można zmodyfikować techniki opisane powyżej.W tym przykładzie metoda odpowiada liczba elementów zwróconych przez moreThan2 w instrukcji switch.

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;
    }
}

Powrót do początkuw tym artykuleW tej sekcjiw tej sekcji

Artykuły o podobnej tematyce

Projektowania wytyczne dotyczące wyjątków (wytyczne dotyczące projektowania platformy .NET Framework)

zwracania wyjątków (oprogramowania Essentials aplikacji .NET Framework) i obsługi

jak: Otrzymuj powiadomienia pierwszej szansy wyjątek (Podręcznik programowania .NET Framework)

jak: obsługi wyjątków w zapytaniu PLINQ (Podręcznik programowania .NET Framework)

Wyjątków w zarządzanych wątków (Podręcznik programowania .NET Framework)

wyjątków i obsługi wyjątków (C# Programming Guide)

instrukcji (C# odwołania) do obsługi wyjątków

Spróbuj...CATCH...Na koniec instrukcji (Visual Basic)

obsługi (F #) wyjątków

Wyjątki C + +/ CLI

(równoległe Biblioteka) obsługi wyjątków

obsługi (debugowanie) wyjątków

Instruktaż: Obsługa wyjątek współbieżności (Uzyskiwanie dostępu do danych w programie Visual Studio)

jak: obsługi błędów i wyjątków, które występują z wiązania danych (Windows Forms)

Obsługa wyjątków w aplikacjach sieci (XAML) (z Windows)

Powrót do początku W tym artykule