Тупик при мошенничестве в .net - PullRequest
2 голосов
/ 28 июля 2011

У меня странная тупиковая ситуация.После прилагается визуальная студия.Я видел 3 темы, которые застряли.

  1. Тема 1:

    if (SomeEvent != null)
       SomeEvent(this, new SomeArg) --> Stuck
    
  2. Тема 2:

    if (SomeEvent2 != null)
        SomeEvent2(this, new SomeArg2) --> Stuck
    
  3. Основная тема:

    public object (Delegate method, object[] args)
    {
       ...
       SynchronizationContext.Send(delegate(object state))
       {
           ...
           method.DynamicInvoke(args); --> Stuck
       }
    }
    

Эти три потока застряли, и когда я проверял их стеки вызовов, я не смог найти ни одного общего ресурса, например lock() или Monitor.Wait().Я полагаю, что все они застряли на внешних вызовах.

Кроме того, я не могу сказать, что делает method.DynamicInvoke(args) и каким должен быть этот метод.

Единственное, что я нашел, эточто подключенные обработчики событий могут вызвать взаимоблокировку.Тем не менее, поскольку VS показал мне, что именно здесь он застрял, а не в коде обработчика событий.Я думаю, что это может быть что-то еще.

С точки зрения приложения, я знаю, что это условие гонки, потому что приложение пыталось выполнить загрузку и выгрузку данных в одно и то же время, так что эта проблема довольно сложная.для воспроизведения.

Мой вопрос:

  1. Почему поток .NET зависает при возникновении события, это вообще возможно?
  2. Нужен ли поток основного интерфейса пользователябудет использоваться при поднятии события?
  3. Если действительно возможно, чтобы событие поднялось в тупик, как мне предотвратить это?

Спасибо

1 Ответ

1 голос
/ 28 июля 2011
  1. Возможно ли зависание потока при создании события? Да, это. Поток выполнения не возвращается от возникновения события до тех пор, пока обработчики событий не будут завершены. Обработчиками событий может быть что угодно, и поэтому они могут зависать. Если обработчик событий зависает, поток, вызывающий события, зависает.

  2. Нет, поток Main UI не нужно использовать для создания событий. Любой поток может вызывать события.

  3. Повышение событий не особенно подвержено тупикам, но оно также не защищено от него. Когда вы вызываете событие, поток, в котором вы находитесь, выполняет любой код, зарегистрированный в качестве обработчика события. Этот код не особенный. Это просто код, выполняющийся в том же потоке, который вызвал событие. Он может заблокировать или нет по тем же причинам, что любой код может заблокировать.

Дело в том, что нет ничего особенного в том, как выполняется код для событий и обработчиков событий. Хотя я упрощаюсь до такой степени, что я почти наверняка ошибаюсь, суть в том, что события - это просто многоадресные делегаты, которые доступны для публичного добавления и удаления элементов из своего списка вызовов, но доступ ко всем остальным формам является закрытым. В событиях нет ничего, что связано с темой. Использование событий не повлияет на существование взаимоблокировки по сравнению с выполнением того же кода в обработчиках событий другим способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...