Можно ли вызывать произвольный код, когда любой управляемый поток завершается в пределах домена приложения? - PullRequest
3 голосов
/ 18 мая 2011

Рассмотрим библиотеку классов, написанную на C #, которая использует специфичные для потока поля в некоторых своих классах. Библиотека классов должна очистить данные, когда поток завершается.

namespace MySdk
{
  public class MyClass
  {
    [ThreadStatic]
    private static SomeData _data; 

    public static SomeData Data
    {
       get
       {
         if(_data == null)
         {
           _data = new SomeData();
         }
         return _data;
       }
    }

    public static void FreeSomeData()
    {
      // Release _data 
    }

    // some other useful data which uses _data

  }  
} 

Есть ли способ вызывать FreeSomeData всякий раз, когда управляемый поток завершается в текущем домене приложения? Из-за сложности приложений, использующих эту библиотеку классов, может быть нецелесообразно явно вызывать метод до завершения потока. Код, запускающий потоки, может даже не знать, что эта библиотека классов существует из-за уровней косвенности.

В нативном коде я сделал бы это в DllMain и проверил fdwReason для DLL_THREAD_DETACH.

Очень ценится.

Ответы [ 2 ]

1 голос
/ 18 мая 2011

SomeData должен иметь финализатор для очистки ресурсов.

Если вам нужна детерминированная очистка, то нет простого решения. API профилирования могут быть использованы для предоставления того, что вам нужно, но было бы намного проще, если бы SomeData внедрило IDisposable и возложило бы ответственность на клиента.

0 голосов
/ 20 мая 2011

Один из вариантов - создать минималистичный класс потока, который обертывает класс System.Threading.Thread. Вместо создания объекта System.Threading.Thread вы можете создать свой собственный объект потока, который делает то же самое, но вызывает FreeSomeData (), когда поток завершается.

Например:

class MyThread
{
    private Action _worker;

    public MyThread(Action worker)
    {
        _worker = worker;
    }

    public void Start()
    {
        var t = new System.Threading.Thread(doWork);
        t.Start();
    }

    private void doWork()
    {
        _worker();
        MyClass.FreeSomeData();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...