To kod wprost z mojej aplikacji, która m.in. musi wczytać ok. 100 pluginów. Ciebie interesuje kod wewnątrz metody "LoadComponentsWorker", a reszta to bajery w stylu pokazywania ilości wczytanych już pluginów (u mnie trochę to trwa, nawet pomimo tego, że są to pluginy po 200-300 linii kodu).
public class ComponentsManager
{
#region Singleton
static ComponentsManager instance = null;
static readonly object padlock = new object();
ComponentsManager()
{
}
public static ComponentsManager Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new ComponentsManager();
}
return instance;
}
}
}
#endregion
List<MoorHunt.MailClient> mailClients = new List<MoorHunt.MailClient>();
public List<MoorHunt.MailClient> MailClients
{
get { return mailClients; }
}
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
}
public void LoadComponentsAsync(string componentsDirectory)
{
LoadComponentsWorkerDelegate worker = new LoadComponentsWorkerDelegate(LoadComponentsWorker);
AsyncCallback completedCallback = new AsyncCallback(LoadComponentsCompletedCallback);
lock (sync)
{
if (isBusy)
{
throw new InvalidOperationException("Components are currently loading.");
}
AsyncOperation async = AsyncOperationManager.CreateOperation(null);
worker.BeginInvoke(componentsDirectory, async, completedCallback, async);
isBusy = true;
}
}
public event EventHandler<LoadComponentsProgressChangedEventArgs> LoadComponentsProgressChanged;
protected virtual void OnLoadComponentsProgressChanged(LoadComponentsProgressChangedEventArgs e)
{
if (LoadComponentsProgressChanged != null)
{
LoadComponentsProgressChanged(this, e);
}
}
public event AsyncCompletedEventHandler LoadComponentsCompleted;
protected virtual void OnLoadComponentsCompleted(AsyncCompletedEventArgs e)
{
if (LoadComponentsCompleted != null)
{
LoadComponentsCompleted(this, e);
}
}
private readonly object sync = new object();
private delegate void LoadComponentsWorkerDelegate(string componentsDirectory, AsyncOperation async);
private void LoadComponentsWorker(string componentsDirectory, AsyncOperation async)
{
this.mailClients.Clear();
string[] componentFiles = Directory.GetFiles(componentsDirectory, "*.dll");
for (int i = 0; i < componentFiles.Length; i++)
{
Assembly componentAssembly = Assembly.LoadFile(componentFiles[i]);
Type[] componentTypes = componentAssembly.GetTypes();
foreach (Type componentType in componentTypes)
{
if (typeof(MoorHunt.MailClient).IsAssignableFrom(componentType))
{
this.mailClients.Add(Activator.CreateInstance(componentType) as MoorHunt.MailClient);
}
}
int progressPercentage = 100 * (i + 1) / componentFiles.Length;
LoadComponentsProgressChangedEventArgs eArgs = new LoadComponentsProgressChangedEventArgs(
progressPercentage, new FileInfo(componentFiles[i]).Name, null);
async.Post(delegate(object e)
{
OnLoadComponentsProgressChanged(e as LoadComponentsProgressChangedEventArgs);
}, eArgs);
}
}
private void LoadComponentsCompletedCallback(IAsyncResult asyncResult)
{
LoadComponentsWorkerDelegate worker = (asyncResult as AsyncResult).AsyncDelegate as LoadComponentsWorkerDelegate;
AsyncOperation async = asyncResult.AsyncState as AsyncOperation;
worker.EndInvoke(asyncResult);
lock (sync)
{
isBusy = false;
}
AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null, false, null);
async.PostOperationCompleted(delegate(object e)
{
OnLoadComponentsCompleted(e as AsyncCompletedEventArgs);
}, completedArgs);
}
public class LoadComponentsProgressChangedEventArgs : ProgressChangedEventArgs
{
private string currentComponent;
public string CurrentComponent
{
get { return currentComponent; }
}
public LoadComponentsProgressChangedEventArgs(int progressPercentage, string currentComponent,
object userState)
: base(progressPercentage, userState)
{
this.currentComponent = currentComponent;
}
}
}