Извините за длинный пост, я просто хочу проиллюстрировать мою ситуацию как можно лучше. Прочитайте элементы, выделенные полужирным шрифтом, и проверьте код, если вы хотите быстро понять суть проблемы.
Я использую ClickOnce для развертывания приложения на C # и предпочел, чтобы мое приложение проверяло наличие обновленийвручную, используя ApplicationDeployment Class вместо того, чтобы позволять ему выполнять проверку обновлений для меня.
Программа представляет собой специализированный сетевой сканер, который выполняет поиск сетевых устройств, созданных компанией, в которой я работаю.Как только главное окно загружено, отображается запрос, спрашивающий, хочет ли пользователь сканировать сеть.Если они говорят «Да», начинается сканирование, которое может занять минуту или две, в зависимости от настроек сети;в противном случае он просто ждет, когда пользователь выполнит какое-либо действие.
Одна из последних вещей, которые я делаю в Form_Load
, - это создание нового потока, который проверяет наличие обновлений.Все это работало нормально в течение нескольких месяцев, примерно через 12 выпусков, и внезапно перестало работать.Я вообще не изменил код обновления и не изменил последовательность действий при запуске приложения.
Смотря на код, я думаю, что вижу, почему он работает неправильно и хотелчтобы подтвердить, что то, что я считаю правильным.Если это так, то возникает вопрос о том, почему он работал раньше - но я тоже не слишком обеспокоен этим.
Рассмотрим следующий код:
frmMain.cs
private void Form1_Load(object sender, EventArgs e)
{
// set up ui, load settings etc
Thread t = new Thread(new ParameterizedThreadStart(StartUpdateThread));
t.Start(this);
}
private void StartUpdateThread(object param)
{
IWin32Window owner = param as IWin32Window;
frmAppUpdater.CheckForUpdate(owner);
}
frmAppUpdater.cs
public static void CheckForUpdate(IWin32Window owner)
{
if (ApplicationDeployment.IsNetworkDeployed) {
Console.WriteLine("Going to check for application updates.");
parentWindow = owner;
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
ad.CheckForUpdateCompleted += new CheckForUpdateCompletedEventHandler(ad_CheckForUpdateCompleted);
ad.CheckForUpdateProgressChanged += new DeploymentProgressChangedEventHandler(ad_CheckForUpdateProgressChanged);
ad.CheckForUpdateAsync();
// CAN/WILL THE THREAD CREATED IN FORM1_LOAD BE TERMINATED HERE???
}
}
Когда обратный вызов CheckForUpdateAsync()
завершается, если обновление недоступно, вызов метода просто возвращается;если доступно обновление, я использую цикл для блокировки до тех пор, пока не произойдут 2 события: пользователь отклонил «Вы хотите сканировать приглашение» И в настоящее время сканирование не выполняется.
Цикл выглядит так, чтопроисходит в ad_CheckForUpdateCompleted
:
while (AppGlobals.ScanInProgress || AppGlobals.ScanPromptVisible) {
System.Threading.Thread.Sleep(5000);
}
Я сплю 5 секунд, потому что я подумал, что это происходит в отдельном потоке, и, кажется, какое-то время он работал хорошо.
Мой главный вопрос по поводу приведенного выше кода:
Когда из CheckForUpdate
вызывается ad.CheckForUpdateAsync();
, завершается ли поток, созданный в Form1_Load
(или он может прерваться)?Я подозреваю, что это возможно, потому что последующий асинхронный вызов заставляет метод возвращаться, а затем запускать другой поток?
Единственная причина, по которой я запутался, заключается в том, что этот метод работал так долго, без зависания приложения, и теперь всенеожиданно зависает, и мои лучшие усилия по отладке показали, что это был спящий вызов, блокирующий приложение.
Я был бы рад выложить полный код для frmAppUpdater.cs, если это будет полезно.