Re[4]: Асинхронное выполнение длительной операции в другом AppDomain
От: Shefango  
Дата: 06.06.13 12:02
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, Shefango, Вы писали:


S>>Не могли бы вы пояснить ваше предложение подробнее?


S>Попробуйте перенести логику создания потока в методы AbstractImport'а.


Последовал вашему совету, получилось так

Form1.cs
private void startButton_Click(object sender, EventArgs e)
{
    string assembly = Environment.CurrentDirectory + "\\Import.dll";
    
    if (File.Exists(assembly))
    {
        StartImport(assembly);
    }
}

private void StartImport(object parameter)
{
    Trace.WriteLine(AppDomain.CurrentDomain.FriendlyName);

    string assembly = (string)parameter;
    AppDomain worker = AppDomain.CreateDomain("Worker");
            
    import = (AbstractImport)worker.CreateInstanceFromAndUnwrap(assembly, "Import.Import1CtoTS");

    if (import != null)
    {
        import.Initialize(this);
        import.ProgressChanged += new Shared.ProgressChangedEventHandler(import_ProgressChanged);
        import.WorkCompleted += new WorkCompletedEventHandler(import_WorkCompleted);
        import.Start("ts", "Superuser", "123");
    }

    AppDomain.Unload(worker);
}


AbstractImport.cs
public abstract class AbstractImport : MarshalByRefObject
{
    private Control owner;
    protected bool cancellationPending = false;
        
    public event ProgressChangedEventHandler ProgressChanged;
    public event WorkCompletedEventHandler WorkCompleted;
        
    abstract public void Start(string config, string user, string pass);

    public void Initialize(Control owner)
    {
        this.owner = owner;
    }

    public abstract void Cancel();
}


Import.cs
public class Import1CtoTS : AbstractImport
{
    public Import1CtoTS()
    {
        Trace.WriteLine("Конструктор Import1CtoTS");
    }

    public override void Start(string config, string user, string pass)
    {
        try
        {
            Thread t = new Thread(StartInternal);
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }
        catch (Exception ex)
        {
            Trace.WriteLine(ex.Message);
        }
    }

    private void StartInternal()
    {
        string config = "ts";
        string user = "Superuser";
        string pass = "123";
            
        try
        {
            Trace.WriteLine("Зашли в поток!");
            Trace.WriteLine(AppDomain.CurrentDomain.FriendlyName);

            OnWorkCompleted(cancellationPending);
        }
        catch (Exception ex)
        {
            Trace.WriteLine(ex.Message);
        }
    }

    public override void Cancel()
    {
        cancellationPending = true;
    }
}


При таком варианте у меня не запускается метод StartInternal. (Не отрабатывает Trace.WriteLine("Зашли в поток!")
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.