Поделиться через


Разрешение вопросов, связанных с исключениями: System.NullReferenceException

Исключение NullReferenceException возникает при попытке использовать метод или свойство ссылочного типа (C#, Visual Basic), значение которого — null. Например, вы могли попытаться использовать объект, сначала не используя ключевое слово new (New в Visual Basic), или использовать объект, значение которого было задано равным null (Nothing в Visual Basic).

Содержание этой статьи

Классы, используемые в этой статье

Основные причины исключений NullReferenceException

Поиск источника исключений NullReferenceExceptions во время разработки

Предотвращение исключений NullReferenceException

Обработка исключений NullReferenceException в коде выпуска

Классы, используемые в этой статье

В большинстве примеров в этой статье используется один или оба следующих класса:

public class Automobile
{
    public EngineInfo Engine {get; set;}
}

public class EngineInfo
{
    public EngineInfo() { }

    public EngineInfo(string powerSrc, double engineSize)
    {
        Power = powerSrc;
        Size = engineSize;
    }

    public double Size { get; set; }
    public string Power = null;
}
   
Public Class Automobile
    Public Property Engine As EngineInfo
End Class

Public Class EngineInfo
    Public Sub New()
    End Sub

    Public Sub New(powerSrc As String, engineSize As Double)
        Power = powerSrc
        Size = engineSize
    End Sub

    Public Property Size() As Double
    Public Power As String = Nothing
End Class

К началуДругие разделы этой статьи

Основные причины исключений NullReferenceException

Любая переменная ссылочного типа может равняться null. Локальные переменные, свойства класса, параметры методов и возвращаемые значения методов могут содержать пустую ссылку. Вызов методов или свойств таких переменных, имеющих значение null, приводит к созданию исключения NullReferenceException. Специальные случаи:

Локальная переменная или поле члена объявлено, но не инициализировано

Свойство или поле имеют значение null

Параметр метода равен null

Возвращаемое значение метода равно null

Объект в коллекции или массиве имеет значение null

Объект не создается из-за условия

Для объекта, передаваемого по ссылке в метод, задано значение null

Локальная переменная или поле члена объявлено, но не инициализировано

Эта простая ошибка чаще всего возникает в коде Visual Basic. За исключением, например, таких случаев, когда объявление переменной передается как выходной параметр, компилятор C# не позволяет использовать локальную ссылочную переменную без ее инициализации. Компилятор Visual Basic создает предупреждение.

  • В следующем коде C# выделенная строка создает данную ошибку компилятора:

Использование неназначенной локальной переменной 'engine'

  • В коде Visual Basic выделенная строка создает предупреждение компилятора BC42104:

Переменная 'engine' используется до того, как ей присвоено значение.  Во время выполнения может произойти исключение, связанное с пустой ссылкой.

При выполнении этой строки создается исключение NullReferenceException.
public void NullReferencFromUninitializedLocalVariable()
{
    EngineInfo engine;
    Console.WriteLine(engine.ToString());
}
Public Sub NullReferencFromUninitializedLocalVariable()
    Dim engine As EngineInfo
    Console.WriteLine(engine.ToString())
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Свойство или поле имеют значение null

Поля и свойства класса автоматически инициализируются с их значением по умолчанию при создании класса. Значение по умолчанию ссылочного типа — null (Nothing в Visual Basic). Вызов методов члена для поля или свойства родительского класса, если значение поля или свойства — null, приводит к созданию исключения NullReferenceException.

В этом примере выделенная строка создает исключение NullReferenceException, так как свойство Engine класса car автоматически инициализируется со значением null.

public void NullReferenceFromProperty()
{
    var car = new Automobile();

    Console.WriteLine(car.Engine.ToString());
}
Public Sub NullReferenceFromProperty()
    Dim car = New Automobile()
    Console.WriteLine(car.Engine.ToString())
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Параметр метода равен null

Параметр метода ссылочного типа может равняться null (Nothing в Visual Basic). Вызов методов или свойств члена при нулевом значении параметра вызывает исключение NullReferenceException.

В этом примере выделенная строка создает исключение NullReferenceException, так как BadEngineInfoPassedToMethod вызывает NullReferenceFromMethodParameter с параметром, значение которого равняется null.

public void BadEngineInfoPassedToMethod()
{
    EngineInfo eng = null;
    NullReferenceFromMethodParameter(eng);
}

public void NullReferenceFromMethodParameter(EngineInfo engine)
{
    Console.WriteLine(engine.ToString());
}
Public Sub BadParameterPassedToMethod() As EngineInfo
    Dim eng As EngineInfo = Nothing
    NullReferenceFromMethodParameter(eng)
End Sub

Public Sub NullReferenceFromMethodParameter(engine As EngineInfo)
    Console.WriteLine(engine.ToString())
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Возвращаемое значение метода равно null

Метод, возвращающий ссылочный тип, может возвращать значение null (Nothing в Visual Basic). Вызов методов или свойств возвращаемого ссылочного типа создает исключение NullReferenceException, если значение ссылки — null.

В этом примере выделенная строка создает исключение NullReferenceException, так как вызов BadGetEngineInfo возвращает пустую ссылку в методе NullReferenceFromMethodParameter.

public EngineInfo BadGetEngineInfo()
{
    EngineInfo engine = null;
    return engine;
}

public void NullReferenceFromMethodReturnValue()
{
    var engine = BadGetEngineInfo();
    Console.WriteLine(engine.ToString());
}
Public Function BadGetEngineInfo() As EngineInfo
    Dim engine As EngineInfo = Nothing
    Return engine
End Function

Public Sub NullReferenceFromMethodReturnValue()
    Dim engine = BadGetEngineInfo()
    Console.WriteLine(engine.ToString())
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Объект в коллекции или массиве имеет значение null

Список или массив ссылочных типов может содержать элемент, значение которого равняется null. Вызов методов или свойств элемента списка, который имеет значение «null», вызывает исключение NullReferenceException.

В этом примере выделенная строка в NullReferenceFromListItem() создает исключение NullReferenceException, так как вызов BadGetCarList возвращает элемент, значение которого — null.

public Automobile[] BadGetCarList()
{
    var autos = new Automobile[10];
    for (int i = 0; i autos.Length; i++)
    {
        if (i != 6)
        {
            autos[i] = new Automobile();
        }
    }
    return autos;
}

public void NullReferenceFromListItem()
{
    var cars = BadGetCarList();
    foreach (Automobile car in cars)
    {
        Console.WriteLine(car.ToString());
    }
}
Public Function BadGetCarList() As Automobile()
    Dim autos = New Automobile(10) {}
    For i As Integer = 0 To 9
        If i <> 6 Then
            autos(i) = New Automobile()
        End If
    Next
    Return autos
End Function

Public Sub NullReferenceFromListItem()
    Dim cars = BadGetCarList()
    For Each car As Automobile In cars
        Console.WriteLine(car.ToString())
    Next
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Объект не создается из-за условия

Если ссылочный тип инициализируется в условном блоке, объект не создается, если условие не выполнено.

В этом примере выделенная строка в NullReferenceFromConditionalCreation создает исключение NullReferenceException, так как она инициализирует переменную engine только в том случае, если метод DetermineTheCondition() возвращает значение true.

 public bool DetermineTheCondition()
{
    return false;
}

public void NullReferenceFromConditionalCreation()
{
    EngineInfo engine = null;
    var condition = DetermineTheCondition();
    if (condition)
    {
        engine = new EngineInfo();
        engine.Power = "Diesel";
        engine.Size = 2.4;
    }
    Console.WriteLine(engine.Size);
}
Public Function DetermineTheCondition() As Boolean
    Return False
End Function

Public Sub NullReferenceFromConditionalCreation()
    Dim engine As EngineInfo = Nothing
    Dim condition = DetermineTheCondition()
    If condition Then
        engine = New EngineInfo()
        engine.Power = "Diesel"
        engine.Size = 2.4
    End If
    Console.WriteLine(engine.Size)
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Свойство объекта, передаваемого методу, задано равным null

При передаче в метод объекта как параметра по значению (не используя ключевое слово ref или out в C# либо ByRef в Visual Basic) метод не может изменить ячейку памяти для параметра (на которую указывает параметр), однако может изменить свойства объекта.

В этом примере метод NullPropertyReferenceFromPassToMethod создает объект Automobile и инициализирует свойство Engine. Затем он вызывает BadSwapCarEngine, передавая новый объект в виде параметра. BadSwapCarEngine задает свойство Engine равным null, что вызывает создание выделенной строкой в NullPropertyReferenceFromPassToMethod исключения NullReferenceException.

public void BadSwapCarEngine(Automobile car)
{
    car.Engine = null;
}

public void (Automobile car)
{
    car.Engine = new EngineInfo("GAS", 1.5);
    BadSwapCarEngine(car);
    Console.WriteLine(car.Engine.ToString());
}
Public Sub BadSwapCarEngine(car As Automobile)
    car.Engine = Nothing
End Sub

Public Sub NullPropertyReferenceFromPassToMethod()
    Dim car As New Automobile()
    car.Engine = New EngineInfo("GAS", 1.5)
    BadSwapCarEngine(car)
    Console.WriteLine(car.Engine.ToString())
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Для объекта, передаваемого по ссылке в метод, задано значение null

При передаче в метод ссылочного типа как параметра по ссылке (используя ключевое слово ref или out в C# или ByRef в Visual Basic) можно изменить расположение памяти, на которое указывает параметр.

При передаче в метод ссылочного типа по ссылке метод может задать для ссылочного типа значение null (ключевое слово Nothing в Visual Basic).

В этом примере выделенная строка в NullReferenceFromPassToMethodByRef создает исключение NullReferenceException, так как вызов метода BadEngineSwapByRef задает для переменной stockEngine значение null.

public void BadEngineSwapByRef(ref EngineInfo engine)
{
    engine = null;
}

public void NullReferenceFromPassToMethodByRef()
{
    var stockEngine = new EngineInfo();
    stockEngine.Power = "Gas";
    stockEngine.Size = 7.0;
    BadSwapEngineByRef(ref stockEngine);
    Console.WriteLine(stockEngine.ToString());
}
Public Sub BadSwapEngineByRef(ByRef engine As EngineInfo)
    engine = Nothing
End Sub

Public Sub NullReferenceFromPassToMethodByRef()
    Dim formatStr = "The stock engine has been replaced by a {0} liter {} engine"
    Dim stockEngine = New EngineInfo()
    stockEngine.Power = "Gas"
    stockEngine.Size = 7.0
    BadSwapEngineByRef(stockEngine)
    Console.WriteLine(stockEngine.ToString())
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Поиск источника исключения NullReferenceException во время разработки

Использование подсказок по данными, окна локальных переменных и окон контрольных значений для просмотра значений переменных

Обход стека вызовов для поиска вызовов, в которых ссылочные переменные не инициализированы или заданы равными null

Настройка условных точек основа для прекращения отладки при обнаружении объектов, имеющих значение null (Nothing в Visual Basic)

Использование подсказок по данными, окна локальных переменных и окон контрольных значений для просмотра значений переменных

  • Наведите указатель мыши на имя переменной, чтобы просмотреть это значение в подсказке по данным. Если переменная ссылается на объект или коллекцию, можно развернуть тип данных для анализа его свойств или элементов.

  • Откройте окно Локальные для анализа активных переменных в текущем контексте.

  • В окне контрольных значений можно просмотреть, как изменяется переменная при прохождении кода.

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Обход стека вызовов для поиска вызовов, в которых ссылочные переменные не инициализированы или заданы равными null

Окно стека вызовов Visual Studio содержит список имен методов, которые не были выполнены из-за остановки отладчика в точке останова или исключении. Для изменения контекста выполнения для метода и анализа его переменных можно выбрать имя в окне Стек вызовов и нажать кнопку Перейти к кадру.

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Настройка условных точек основа для прекращения отладки при обнаружении объектов, имеющих значение null (Nothing в Visual Basic)

Можно задать условную точку останова, чтобы прерывать выполнение, если переменная имеет значение null. Условные точки останова могут быть полезны, когда пустая ссылка не возникает слишком часто, например, когда элемент в коллекции принимает значение null только периодически. Еще одним преимуществом использования условных точек останова является то, что они позволяют выполнять отладку проблемы до ее передачи в конкретную подпрограмму обработки.

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Предотвращение исключений NullReferenceException

Использование оператор Debug.Assert для проверки инварианта

Полная инициализация ссылочных типов

Использование оператор Debug.Assert для проверки инварианта

Инвариант представляет собой условие, в истинности которого вы уверены. Оператор Debug.Assert (System.Diagnostics) вызывается только из сборок отладки приложения, но не из кода выпуска. Если инвариантное условие не соблюдается, отладчик прерывает выполнение кода в операторе Assert и выводит диалоговое окно. Debug.Assert обеспечивает проверку того, что условие не изменялось во время разработки приложения. Утверждение также уведомляет других пользователей, читающих ваш код, о том, что условие должно всегда иметь значение true.

Например, метод MakeEngineFaster предполагает, что его параметр engine никогда не будет иметь значение null, так как известно, что единственный вызывающий его метод (TheOnlyCallerOfMakeEngineFaster) полностью инициализирует EngineInfo. Оператор assert в методе MakeEngineFaster документирует предположение и выполняет проверку его соблюдения.

Если разработчик добавляет новый вызывающий метод (BadNewCallerOfMakeEngineFaster), который не инициализирует параметр, то срабатывает оператор assert.

private void TheOnlyCallerOfMakeEngineFaster()
{
    var engine = new EngineInfo();
    engine.Power = "GAS";
    engine.Size = 1.5;
    MakeEngineFaster(engine);
}

private void MakeEngineFaster(EngineInfo engine)
{
    System.Diagnostics.Debug.Assert(engine != null, "Assert: engine != null");
    engine.Size *= 2;
    Console.WriteLine("The engine is twice as fast");
}

private void BadNewCallerOfMakeEngineFaster()
{
    EngineInfo engine = null;
    MakeEngineFaster(engine);
}
Public Sub TheOnlyCallerOfMakeEngineFaster()
    Dim engine As New EngineInfo
    engine.Power = "GAS"
    engine.Size = 1.5
    MakeEngineFaster(engine)
End Sub

Private Sub MakeEngineFaster(engine As EngineInfo)
    System.Diagnostics.Debug.Assert(engine IsNot Nothing, "Assert: engine IsNot Nothing")
    engine.Size = engine.Size * 2
    Console.WriteLine("The engine is twice as fast")
End Sub

Public Sub BadNewCallerOfMakeEngineFaster()
    Dim engine As EngineInfo = Nothing
    MakeEngineFaster(engine)
End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Полная инициализация ссылочных типов

Чтобы избежать массового возникновения исключений NullReferenceException, выполните полную инициализацию ссылочных типов как можно скорее после их создания.

Добавление полной инициализации в собственные классы

Если вы можете управлять классом, который создает исключение NullReferenceException, рекомендуется выполнять полную инициализацию объекта в конструкторе типа. Например, ниже приведена исправленная версия примеров классов, которая гарантирует полную инициализацию:

public class Automobile
{
    public EngineInfo Engine { get; set; }

    public Automobile() 
    { 
        this.Engine = new EngineInfo(); 
    }

    public Automobile(string powerSrc, double engineSize)
    {
        this.Engine = new EngineInfo(powerSrc, engineSize);
    }
}


public class EngineInfo
{
    public double Size {get; set;}
    public string Power {get; set;}

    public EngineInfo() 
    { 
        // the base engine 
        this.Power = "GAS"; 
        this.Size = 1.5; 
    }

    public EngineInfo(string powerSrc, double engineSize)
    {
        this.Power = powerSrc;
        this.Size = engineSize;
    }
}
Public Class Automobile
    Public Property Engine As EngineInfo

    Public Sub New() 
        Me.Engine = New EngineInfo() 
    End Sub 

    Public Sub New(powerSrc As String, engineSize As Double) 
        Me.Engine = New EngineInfo(powerSrc, engineSize) 
    End Sub

End Class

Public Class BaseEngineInfo
    Public Sub New() 
        ' the base engine 
        Me.Power = "GAS" 
        Me.Size = 1.5 
    End Sub

    Public Sub New(powerSrc As String, engineSize As Double)
        Power = powerSrc
        Size = engineSize
    End Sub

    Public Property Size() As Double
    Public Power As String = String.Empty
End Class

Примечание

Использование отложенной инициализации для больших или редко используемых свойств

Чтобы сократить использование памяти для класса и повысить производительность, рекомендуется использовать отложенную инициализацию свойств ссылочных типов.См. раздел Отложенная инициализация.

Обработка исключений NullReferenceException в коде выпуска

Проверка значений null (Nothing в Visual Basic) перед использованием ссылочного типа

Использование конструкции try – catch – finally (Try – Catch – Finally в Visual Basic) для обработки исключения

Лучше избегать исключения NullReferenceException, чем обрабатывать его после возникновения. Обработка исключений может затруднять обслуживание и понимание вашего кода, а иногда даже приводить к другим ошибкам. Исключение NullReferenceException часто является неисправимой ошибкой. В этом случае, возможно, будет лучше позволить исключению остановить приложение.

Однако существует много ситуаций, в которых процесс обработки ошибки может оказаться полезен:

  • Приложение может пропускать объекты, которые имеют значение null. Например, если приложение получает и обрабатывает записи в базе данных, можно игнорировать некоторое число неверных записей, которые вызывают возникновение объектов со значением null. Возможно, все, что потребуется, — записать неверные данные в файл журнала или интерфейс пользователя приложения.

  • Можно попытаться исправить исключение. Например, вызов веб-службы, который возвращает ссылочный тип, может вернуть значение null в случае разрыва или истечения времени ожидания подключения. Можно попытаться восстановить подключение и повторить вызов.

  • Можно восстановить приложение до допустимого состояния. Например, вы могли выполнять задачу, состоящую из нескольких шагов, которая требует сохранения информации в хранилище данных, перед вызовом метода, который создает исключение NullReferenceException. Если неинициализированный объект повредит запись данных, можно будет удалить предыдущие данные перед закрытием приложения.

  • Требуется сообщить об исключении. Например, если ошибка была вызвана неправильным действием пользователя приложения, можно создать сообщение, которое поможет ему предоставить правильные сведения. Кроме того, можно зарегистрировать сведения об ошибке, которые помогут устранить проблему. Некоторые платформы, например, ASP.NET, содержат высокогоуровневый обработчик исключений, который перехватывает все ошибки, чтобы приложения никогда аварийно не завершало работу; в этом случае только благодаря регистрации исключения вы сможете узнать о наличии ошибки.

Ниже рассмотрены два способа обработки исключения NullReferenceException в коде выпуска.

Проверка значений null (Nothing в Visual Basic) перед использованием ссылочного типа

Использование явной проверки значений null перед использованием объекта позволяет избежать потери производительности конструкций try-catch-finally. Тем не менее, вы по-прежнему должны определять и реализовывать действие в ответ на появление неинициализированного объекта.

В этом примере CheckForNullReferenceFromMethodReturnValue проверяет возвращаемое значение метода BadGetEngineInfo. Если объект не имеет значение null, он используется; в противном случае метод сообщает об ошибке.

public EngineInfo BadGetEngineInfo()
{
    EngineInfo engine = null;
    return engine;
}

public void CheckForNullReferenceFromMethodReturnValue()
{
    var engine = BadGetEngineInfo();
    if(engine != null)
    {
        // modify the info
        engine.Power = "DIESEL";
        engine.Size = 2.4;
    }
    else
    {
        // report the error
        Console.WriteLine("BadGetEngine returned null")
    }
}
public EngineInfo BadGetEngineInfo()
{
    EngineInfo engine = null;
    return engine;
}
Public Sub CheckForNullReferenceFromMethodReturnValue()
    Dim engine = BadGetEngineInfo()
    If (engine IsNot Nothing) Then
        ' modify the info
        engine.Power = "DIESEL"
        engine.Size = 2.4
    Else
        ' report the error
        Console.WriteLine("BadGetEngineInfo returned Nothing")
    End If

End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Использование конструкции try-catch-finally (Try-Catch-Finally в Visual Basic) для обработки исключения

Использование встроенных конструкций обработки исключений (try, catch, finally в C#, Try, Catch, Finally в Visual Basic) предоставляет дополнительные возможности обработки исключений NullReferenceException, помимо проверки того, что используемый объект не имеет значение null.

В этом примере метод CatchNullReferenceFromMethodCall использует два оператора assert для проверки предположения о том, что его параметр содержит полный "автомобиль" (automobile), включая "двигатель" (engine). В блоке try выделенная строка создает исключение NullReferenceException, так как вызов метода RarelyBadEngineSwap может разрушить свойство Engine автомобиля. Блок catch перехватывает исключение, записывает сведения об исключении в файл и сообщает об ошибке пользователю. В блоке finally метод следит за тем, что состояние "машины" (car) было не хуже, чем в начале метода.

public void RarelyBadSwapCarEngine(Automobile car)
{
    if ((new Random()).Next() == 42)
    {
        car.Engine = null;
    }
    else
    {
        car.Engine = new EngineInfo("DIESEL", 2.4);
    }
}

public void CatchNullReferenceFromMethodCall(Automobile car)
{
    System.Diagnostics.Debug.Assert(car != null, "Assert: car != null");
    System.Diagnostics.Debug.Assert(car.Engine != null, "Assert: car.Engine != null");

    // save current engine properties in case they're needed
    var enginePowerBefore = car.Engine.Power;
    var engineSizeBefore = car.Engine.Size;

    try
    {
        RarelyBadSwapCarEngine(car);
        var msg = "Swap succeeded. New engine power source: {0} size {1}";
        Console.WriteLine(msg, car.Engine.Power, car.Engine.Size);
    }
    catch(NullReferenceException nullRefEx)
    {
        // write exception info to log file
        LogException(nullRefEx);
        // notify the user
        Console.WriteLine("Engine swap failed. Please call your customer rep.");
    }
    finally
    {
        if(car.Engine == null)
        {
            car.Engine = new EngineInfo(enginePowerBefore, engineSizeBefore);
        }
    }
}
Public Sub RarelyBadSwapCarEngine(car As Automobile)
    If (New Random()).Next = 42 Then
        car.Engine = Nothing
    Else
        car.Engine = New EngineInfo("DIESEL", 2.4)
    End If
End Sub

Public Sub CatchNullReferenceFromMethodCall(car As Automobile)
    System.Diagnostics.Debug.Assert(car IsNot Nothing)
    System.Diagnostics.Debug.Assert(car.Engine IsNot Nothing)

    ' save current engine properties in case they're needed
    Dim powerBefore = car.Engine.Power
    Dim sizeBefore = car.Engine.Size

    Try
        RarelyBadSwapCarEngine(car)
        Dim msg = "Swap succeeded. New engine power source: {0} size {1}"
        Console.WriteLine(msg, car.Engine.Power, car.Engine.Size)
    Catch nullRefEx As NullReferenceException
        ' write exception info to log file
        LogException(nullRefEx)
        ' notify user
        Console.WriteLine("Engine swap failed. Please call your customer rep.")
    Finally
        If car.Engine Is Nothing Then car.Engine = New EngineInfo(powerBefore, sizeBefore)
    End Try

End Sub

К началуЗаписи в этом разделе

К началуСодержание этой статьи

Связанные статьи

Правила разработки исключений (Разработка на .NET Framework)

Обработка и создание исключений (Основные сведения о приложениях .NET Framework)

Практическое руководство. Получение уведомлений о первичном исключении (Руководство по разработке .NET Framework)

Практическое руководство. Обработка исключений в запросе PLINQ (Руководство по разработке .NET Framework)

Исключения в управляемых потоках (Руководство по разработке .NET Framework)

Исключения и обработка исключений (Руководство по программированию на C#)

Операторы обработки исключений (Справочник по C#)

Оператор Try...Catch...Finally (Visual Basic)

Обработка исключений (F#)

Исключения в C++/CLI

Обработка исключений (Библиотека параллельных задач)

Обработка исключений (Отладка)

Пошаговое руководство. Обработка исключения параллелизма (Доступ к данным в Visual Studio)

Практическое руководство. Обработка ошибок и исключений, происходящих при связывании данных (Windows Forms)

Обработка исключений в сетевых приложениях (XAML) (Windows)

К началуСодержание этой статьи