#c# #winforms
Вопрос:
[использование VS Community 2019 v16.10.4 на Win 10 Pro 202H]
Я работаю над настольным приложением C# Winforms, которое отслеживает некоторые свойства локального диска и отображает сообщение о состоянии. Если диск, выбранный для мониторинга, отсутствует, отображается сообщение об ошибке, предоставляющее пользователю возможность подключить отсутствующие диски, а не запускать анализ повторно.
Когда я подключаю «отсутствующий» диск и повторно запускаю сканирование/анализ, изменение не фиксируется, даже если проводник/файловый менеджер Windows обнаруживает изменение.
Если я завершу и затем перезапущу сеанс отладки, изменения будут приняты, и если я использую поле со списком (временно запускаю обычное окно) для ручной проверки повторного создания экземпляра, изменения будут приняты.
Форма получения данных-это запись в приложении; она выполняет сбор данных с помощью a BackgroundWorker
. Он запускается свернутым и не отображается на панели задач. Я установил точку останова в форме сообщения об ошибке в строке создания нового экземпляра исходной формы. Когда я выполняю шаг (F11), он начинается не с начала кода начальной формы, а частично вниз, где объявлено и назначено поле PercentComplete:
ReadinessStartup refresh = new ReadinessStartup(); //breakpoint here
refresh.Show();
public partial class ReadinessStartup : Form
{
public static DriveInfo[] _allDrives = DriveInfo.GetDrives();
private static readonly List<MonitorDrvs> _monitoredDrives =
ConnectionConfig.Connects.GetMonitoring();
private static System.Timers.Timer _myTimer;
private readonly static int _mDrvsNum = _monitoredDrives.Count;
private volatile bool _progFlag;
private double _elapsedTime;
private double _estTotal;
private double _percentComplete = 0; // ENTERS FORM HERE ON F11
private int _allDrvsNum;
private int _progBarPC;
public static bool _Refresh;
public ReadinessStartup()
{
InitializeComponent();
InitializeBackgroundWorker();
bgWorker.RunWorkerAsync();
}
Таким образом, похоже, что он не принимает изменения, потому что требуемая декларация не обрабатывается. Почему код формы не начинается с самого начала?
Любая помощь будет оценена по достоинству.
= = = = Уточняющее редактирование ====
к комментарию @Jimi: Решение состоит из трех проектов: проекта настройки, проекта мониторинга и библиотеки классов. Настройка выполняется из меню «Пуск», а мониторинг-из планировщика задач. _montoredDrives определяется в настройках и «потребляется» в мониторинге. _allDrives и _montoredDrives используются в методах, вызываемых в DoWork BackgroundWorker, для определения того, отсутствуют ли в настоящее время или изменены диски, определенные для мониторинга (на разных дисках/разделах). DriveInfo[] используется вместо списка, поскольку для анализа необходимы различные свойства использования диска (в частности, размер, свободное и используемое пространство).
Комментарии:
1. Удалить
static
изpublic static DriveInfo[]
. Не ясно, для чего используется это поле или_monitoredDrives
для чего оно используется (используется/установлено изDoWork
события вашего фонового работника?). Это тоже не должно быть публичным. — Если вам нужна свежая информация, вы должны позвонитьDriveInfo.GetDrives()
, когда это необходимо. Содержимое массива не обновляется само по себе (вероятно, это должно быть aList<DriveInfo>
).2. @Jimi Я уже добавил вызов «JIT» в DriveInfo.GetDrives( ) в методе, где он необходим в первую очередь, но я рассматривал его как «обходной путь»; думаю, это не так. Инструкция GetDrives получена из примера Microsoft, и да, она должна быть закрытой, но почему «статическая» должна быть удалена (я только новичок)?
3. В противном случае он инициализируется статически : только тогда, когда инициализируется первый экземпляр класса, к которому он принадлежит. Больше не надо. Таким образом, у вас всегда будет только статическое представление
DriveInfo
результатов (в виде инициализированного массива). — Нет никаких причин, чтобы эта_allDrives
коллекция была статичной , когда это динамическое значение. Вы можете делать запросыDriveInfo.GetDrives()
в любое время, когда это необходимо.
Ответ №1:
Поля объявляются во время компиляции. Вот почему отладчик не берет его. Причина, по которой он начинается с PercentComplete, связана с назначением, которое выполняется во время выполнения
Изменить: проигнорируйте этот ответ (остается здесь для исторических целей). Похоже, мое понимание статики неверно
Комментарии:
1. Поэтому компилируйте только один раз и запускайте по мере необходимости, но разве «public static DriveInfo[] _allDrives = DriveInfo.GetDrives( );» не является также назначением?
2. Да, но это делается при запуске программы, поэтому я предполагаю, что отладчик не подхватывает ее, так как она запускается не при создании экземпляра класса, а при запуске программы
3. @DownloadPizza — Он не запускается при запуске программы. Он запускается, как только к любому
static
члену будет получен доступReadinessStartup
или когдаReadinessStartup
будет создан экземпляр.