Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Если в документации для интерфейса явно не указано иное, вы должны вызывать EndInvoke для каждого места, в котором вы вызываете BeginInvoke. Основная причина в том, что EndInvoke - это единственный раз, когда владелец может безопасно освободить определенные ресурсы, которые могут быть выделены для вызова BeginInvoke (например, WaitHandle).
Но есть исключения из этого правила. API, такие как Control.BeginInvoke, не требуют EndInvoke, но это явно указано в документации.
Оба верны - это разные вызовы.
В целом всегда следует вызывать EndInvoke
, чтобы гарантировать, что любые ресурсы, полученные асинхронным вызовом, будут выпущен.
Однако группа разработчиков Windows Forms гарантирует, что вам не нужно делать это для Control.Invoke
. Возможно, вам придется сделать это для других реализаций ISynchronizeInvoke
, хотя
Раньше я использовал метод «запустил и забыл» с делегатами, когда результаты были «полезны, если доступны, но не требуются». Просто помните, что у вас нет гарантий завершения с этим методом. В частности, вот одно место, в котором я его использую:
В любом случае приложение продолжает работать бесперебойно.