Я изучаю C#. Я читал книги Эндрю Троелсена «C# и .NET Platform» и «CLR через C#» Джеффри Рихтера. Теперь я пытаюсь создать приложение, которое будет загружать сборки из какого-либо каталога, подталкивать их к AppDomain и запускать включенный метод (приложение, которое поддерживает подключаемые модули). Вот DLL, где общий интерфейс. Я добавляю его в свое приложение и во все DLL-файлы с плагинами. MainLib.DLLСбой приложения, когда исключение домена anoter исключает
namespace MainLib
{
public interface ICommonInterface
{
void ShowDllName();
}
}
Здесь вы плагинами: PluginWithOutException
namespace PluginWithOutException
{
public class WithOutException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
MessageBox.Show("PluginWithOutException");
}
public WithOutException()
{
}
}
}
и еще одно: PluginWithException
namespace PluginWithException
{
public class WithException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
MessageBox.Show("WithException");
throw new NotImplementedException();
}
}
}
А вот приложение, которое загружает библиотеки DLL и запускает их в другой AppDomain's
namespace Plug_inApp
{
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(CreateDomainAndLoadAssebly, @"E:\Plugins\PluginWithException.dll");
Console.ReadKey();
}
public static void CreateDomainAndLoadAssebly(object name)
{
string assemblyName = (string)name;
Assembly assemblyToLoad = null;
AppDomain domain = AppDomain.CreateDomain(string.Format("{0} Domain", assemblyName));
domain.FirstChanceException += domain_FirstChanceException;
try
{
assemblyToLoad = Assembly.LoadFrom(assemblyName);
}
catch (FileNotFoundException)
{
MessageBox.Show("Can't find assembly!");
throw;
}
var theClassTypes = from t in assemblyToLoad.GetTypes()
where t.IsClass &&
(t.GetInterface("ICommonInterface") != null)
select t;
foreach (Type type in theClassTypes)
{
ICommonInterface instance = (ICommonInterface)domain.CreateInstanceFromAndUnwrap(assemblyName, type.FullName);
instance.ShowDllName();
}
}
static void domain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
}
}
}
Я ожидаю, что если я запустил instance.ShowDllName();
в другом домене (возможно, я делаю это неправильно?) Необработанное исключение приведет к удалению домена, где он выполняется, но домен по умолчанию будет работать. Но в моем случае - по умолчанию происходит сбой домена после исключения в другом домене. Пожалуйста, скажи мне, что я делаю неправильно?
Вы ошибаетесь. Необработанное исключение в * любом appdomain * приведет к уничтожению * всего процесса *. – dlev
Вам либо нужно обработать исключение, либо это приведет к разрушению всего процесса. http://stackoverflow.com/questions/7071957/appdomain-handling-the-exceptions – Dave
Хорошо, есть ли способы поймать это исключение, показать MessageBox с чем-то вроде «Сбой PluginsWithException», и приложение не будет разбиваться? –