NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
Многопоточное программирование трудно схватить в начале (и ветераны все еще иногда перестали работать), и BackgroundWorker делает немного легче использовать. Мне нравится то, что BackgroundWorker имеет функциональность, которую легко реализовать, но еще легче неправильно реализовать тонким способом, как отмена. Я использую его, если я имею и нуждаюсь в обновлении прогресса, таким образом, я могу отобразить значимый индикатор выполнения.
В противном случае я использую Поток (или заимствую у ThreadPool), потому что мне не нужна вся функциональность BackgroundWorker, и является достаточно опытным с потоками, чтобы запустить Поток и ожидать его для остановки.
Что касается делегатов к несвязанным задачам, я использую те из классов Потока, как плоскость void ThreadStart()
, или я создаю свое собственное.
BackgroundWorker делает вещи намного легче. Одной вещью я нашел твердый путь, является сам Backgroundworker, имеет привязку потока даже при том, что это, как предполагается, скрывает проблему переключения потока. Это автоматически не переключается на поток UI в каждом случае. Это должно быть создано и выполнено от потока UI для потока, переключающегося для случая правильно.
Я использую его довольно часто для задач, таких как признак прогресса и фоновые данные loading\processing.
Недавно я нашел вариант использования, который не поддерживается из поля. Это - "Переопределяемая Задача". Однако Patric Smacchia предлагает хорошее решение.
Я использовал его однажды, и было довольно довольно им. Часто, нет никакой потребности в "большой" многопоточности, но только в 2 Потоках (UI и Рабочий), и это работает действительно хорошо, не имея необходимость волноваться слишком много о базовой Логике Поточной обработки.
Моя самая большая проблема с фоновым классом рабочего - то, что действительно нет никакого способа знать, когда рабочий закончил из-за отмены. BackgroundWorker не выставляет поток, который он использует так, Вы не можете использовать стандартные методы для синхронизации завершения потока (соединение, и т.д.). Вы также не можете только ожидать в цикле на потоке UI, чтобы он закончился, потому что событие RunWorkerCompleted никогда не будет заканчивать тем, что стреляло. Взлом, который я должен был всегда использовать, должен просто установить флаг и затем запустить таймер, который продолжит проверять на второстепенного рабочего для окончания. Но это очень грязно и усложняет бизнес-логику.
Таким образом, это является большим, пока Вы не должны поддерживать детерминированную отмену.
@Gulzar Спасибо за эту часть информации: Это должно быть создано и выполнено от потока UI для потока, переключающегося для случая правильно.
Одной вещью наблюдать за при использовании второстепенного рабочего, которого я нашел, является обработка исключений.
Если исключение будет выдано на асинхронном процессе, то это не выдаст исключение к основному потоку, процесс закончится, и событие BackgroundWorker RunWorkerCompleted будет стрелять с ошибкой скрытый в RunWorkerCompletedEventArgs. Ошибка.
Мне нравится то, что BackgroundWorker имеет функциональность, которую легко реализовать, но еще легче неправильно реализовать тонким способом, как отмена.