aush, спасибо! Заработало.
Для тех, кому актуально - привожу код:
DLL-ка с долгоиграющим процессом (LongRunningTask):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;//чисто для задержки потоков, т.е. для симуляции долгоиграющего процесса
namespace LongRunningTask
{
public class LongRunningTaskPerformer
{
//Интерфейс оповещения, реализуемый клиентом, которому интересно состояние долгоиграющего процесса.
//В нашем случае это форма запуска.
private readonly INotifyProgress _notifier;
public LongRunningTaskPerformer(INotifyProgress notifier)
{
if (notifier != null)
{
_notifier = notifier;
}
}
public void Run()
{
//После каждого шага вызываем метод-оповещатель Notify. В случае с формой в реализации этого метода будет обновление прогресс-бара.
DoStep1();
_notifier.Notify(33);
DoStep2();
_notifier.Notify(66);
DoStep3();
_notifier.Notify(100);
}
private void DoStep1()
{
Debug.WriteLine("Step 1");
Thread.Sleep(12000);
Debug.WriteLine("Step 1 completed!");
}
private void DoStep2()
{
Debug.WriteLine("Step 2");
Thread.Sleep(12000);
Debug.WriteLine("Step 2 completed!");
}
private void DoStep3()
{
Debug.WriteLine("Step 3");
Thread.Sleep(12000);
Debug.WriteLine("Step 3 completed! Work done.");
}
}
}
В рамках этой DLL-ки - интерфейс-оповещатель INotifyProgress:
namespace LongRunningTask
{
public interface INotifyProgress
{
void Notify(int percent);
}
}
А вот основной проект, в котором содержится форма запуска, использующая BackgroundWorker при обновлении прогресс-бара (MyProgressBar):
namespace MyProgressBar
{
//Наша форма запуска реализует интерфейс оповещения INotifyProgress. Это надо, чтобы форма смогла получать данные о состоянии долгоиграющего процесса
//ПО МЕРЕ его выполнения. Без реализации интерфейса ничего работать не будет!
public partial class frmProgressBar : Form, INotifyProgress
{
//Класс, выполняющий наш долгоиграющий процесс
LongRunningTaskPerformer _ltp;
//Делегат, воспроизводящий внешний вид метода-оповещателя из интерфейса INotifyProgress.
//Он нужен для обеспечения потокобезопасной передачи данных в форму. Если его не будет, программа вылетит
//с исключением типа "обращение к progressBar не из его потока" (или что-то подобное).
delegate void NotifyCallback(int value);
public frmProgressBar()
{
InitializeComponent();
}
//Сам процесс запускается с помощью backgroundWorker-а. Кнопка Run только запускает этот backgroundWorker.
private void btnRun_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//Выполнение долгоиграющего процесса.
_ltp = new LongRunningTaskPerformer(this);
_ltp.Run();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Как-то показываем, что у нас завершился наш долгоиграющий процесс и возвращаем прогресс-бар в исходное состояние.
MessageBox.Show("Process completed!");
progressBar1.Value = 0;
}
//Реализация процедуры оповещения о состоянии долгоиграющего процесса.
public void Notify(int percent)
{
//Чтобы передача состояния процесса сработала корректно и программа не вылетела,
//надо делать в точности как здесь (за подробностями - MSDN:
//http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k%28EHInvalidOperation.WinForms.IllegalCrossThreadCall%29;k%28TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5%29;k%28DevLang-csharp%29&rd=true)
if (progressBar1.InvokeRequired)
{
NotifyCallback d = new NotifyCallback(Notify);
this.Invoke(d, new object[] { percent });
}
else
{
progressBar1.Value = percent;
}
}
}
}