Самостоятельно выбрасывающий класс - PullRequest
3 голосов
/ 28 февраля 2011

У меня есть класс, который управляет процессом. При вызове Stop() или Dispose() для этого класса, он сначала отправит TCP-команду процессу, чтобы попросить его закрыть себя, затем вернется через 1 секунду, если он не близок, вызовите CloseMainWindow(), затем подождите еще один секунд, если он все еще работает, позвоните Kill().

Теперь у меня есть List<> этого класса для управления кучей процессов. Когда я хотел бы удалить их из списка, я бы вручную вызвал Dispose(), затем Remove(). Я хочу убедиться, что я позвонил Dispose(), прежде чем потерять единственную ссылку. Поскольку для вызова Dispose() потребуется не менее 2 секунд, чтобы вернуться, потребуется некоторое время, если я скажу, что 5 пунктов должны быть удалены.

Итак, я намеревался создать еще одну функцию с именем SafeDispose(), которую затем можно вернуть Invoke() Dispose(). Теперь удаление их из списка и вызов SafeDispose() вместо Dispose() будут незамедлительными, в то время как сами классы медленно избавляются от них.

Желательно ли это сделать?

Ответы [ 3 ]

2 голосов
/ 28 февраля 2011

По сути, вы предлагаете оставить Dispose «как есть» и вместо этого использовать вспомогательный метод, который асинхронно разрушает объект - который присоединяется к объекту.

Желательно ли?

Возможно, , хитрая вещь во введении потоков - это весь беспорядок потоков, который идет с ним.

  • Что происходит, когда другой метод обращается к объекту, когда он асинхронно удаляется?
  • Что происходит, когда другой AsyncDispose вызывается одновременно?
  • Как распространяются ошибки?
  • Это приведет к тупикам?
  • Не вызовет ли выполнение большого количества утилизации в разных потоках (и разных объектах) какие-либо проблемы? (как из-за отсутствия сокетов tcp)

Если вы можете ответить на все удовлетворительно, тогда, возможно.

Имейте в виду, что в пользовательском интерфейсе можно также выделить поток, который обрабатывает весь срок действия и делает это в одном потоке (в качестве другого варианта)

0 голосов
/ 28 февраля 2011

Используйте асинхронный метод invoke для удаления объектов и удаления их из списка.

Скажем, у вас есть список класса foo, который вы хотите назвать, foos .

var iars = new List<IAsyncResult>();
Action<IDisposable> disposeAction = a => a.Dispose();
foreach(var foo in foos)
    iars.Add(disposeAction.BeginInvoke(null, null));
foreach(var iar in iars)
    disposeAction.EndInvoke(iar);
foreach(var foo in foos) foos.Remove(foo);

Если вы используете .net 4.0, вы можете сделать это с помощью библиотеки Parallel для большей эффективности. Редактировать - популярный спрос на List.Remove поток безопасности. Что касается исключений безопасности. Метод Dispose () никогда не должен генерировать исключение.

0 голосов
/ 28 февраля 2011

Используйте событие вместо

class Program
{
    static void Main(string[] args)
    {
        using (MyClass c = new MyClass())
        {
            c.Disposed += MyClass_Disposed;
            Console.WriteLine("Press any key to dispose");
            Console.ReadKey();
        }
        Console.WriteLine("Press any key to finish");
        Console.ReadKey();
    }

    static void MyClass_Disposed(object source, EventArgs e)
    {
        Console.WriteLine("I've been disposed");
    }
}


class MyClass : IDisposable
{
    public event EventHandler Disposed;

    public void Dispose()
    {
        if (this.Disposed != null)
            this.Disposed(this, EventArgs.Empty);
    }
}
...