Короче говоря, из-за изменяющихся бизнес-требований мне нужно иметь возможность показать конечному пользователю ход процесса архивирования файлов, управляемого консольным приложением C#. Консольное приложение по существу получает список локальных файлов из базы данных, а затем копирует их в папку архива. Первоначально предполагалось, что это фоновый процесс, запускаемый запланированной задачей. Однако теперь пользователи могут запускать его вручную с различными аргументами из командной строки, поэтому недавно передо мной стояла задача сообщить пользователю о состоянии процесса архивирования.
Я думал, что просто использую для этого элемент управления WPF ProgressBar, но теперь я хожу по кругу, пытаясь найти лучший способ сделать это. Я работал с ответом @JamesWilkins здесь: окно WPF из консольного проекта?
Я добавил окно ProgressBar в консольное приложение и добавил следующее в метод Main в консоли (упрощено для ясности):
[STAThread]
static void Main(string[] args)
{
// EXISTING CONSOLE LOGIC
ParseCommandLineArgs();
Configure();
// ADDED
InitializeWindows(); // opens the WPF window and waits here
// EXISTING CONSOLE LOGIC
BeginArchival();
}
static void InitializeWindows()
{
WinApp = new Application();
WinApp.Run(ProgressBar = new ProgressBar()); // blocking call
}
Затем в коде ProgressBar.xaml:
public partial class ProgressBar : Window
{
public ProgressBar()
{
InitializeComponent();
}
private void ProgressBar_OnContentRendered(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// foreach file that is archived, report progress to the
// ProgressBar.
for (int i = 0; i < 100; i++)
{
(sender as BackgroundWorker).ReportProgress(i);
}
}
private void worker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
PbArchiveStatus.Value = e.ProgressPercentage;
}
}
Процесс ожидает в методе InitializeWindows() до тех пор, пока индикатор выполнения не закроется, поэтому он не затрагивает какую-либо логику архивирования, для которой мне нужен индикатор выполнения для отображения прогресса. Кажется, мне по существу нужно поместить всю существующую консольную логику в метод ProgressBar.worker_DoWork(), но в этот момент мой мозг начинает болеть, поэтому я подумал, что протяну руку.
Я на правильном пути, или есть лучший способ добавить индикатор выполнения на основе графического интерфейса в консольную утилиту? Дайте мне знать, если я могу что-то прояснить.