Можно ли создать безопасный многопоточный класс - C#
Формулировка задачи:
Всем еще раз привет.
Пишу класс, который общается с USB- устройством. У него есть методы, запускающие потоки инициализации, запуска устройства и т.д. На время их выполнения я подумал лучше запереть класс, чтобы не дай бог вдальнейшем эти методы не были вызваны одновременно в нескольких потоках.
Пока все хорошо. Но дальше мне хочется еще прикрутить интерфейс IDisposable.
Ну и как вы понимаете, если писать так, если запирать Dispose способом (1) на тот же самый объект, что и Init и другие внешние методы, то в случае, если такой метод зависнет, Dispose не срубит этот поток никогда.
Подскажите, как тут сделать грамотно. Как вообще организуется структура в таких случаях?
public partial class DeviceCommunicator
{
public void BeginInit( /*...*/ )
{
_initThread = new Thread( Init );
_initThread.Start( /*...*/ );
}
private void Init( Object @params )
{
lock( _commonSyncObject )
{
if( _state != DeviceCommunicatorState.idle )
return;
// возможно долгая операция
_state = DeviceCommunicatorState.ready;
}
}
// то же для Start и других функций
}
public partial class DeviceCommunicator
{
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
protected virtual void Dispose( Boolean disposing )
{
lock( _commonSyncObject ) /* (1) */
{
if( disposing )
{
// в зависимости от состояния устройства
switch( _state )
{
case DeviceCommunicatorState.idle : /* ... */
case DeviceCommunicatorState.initializing :
/* соответствующее удаление, в том числе снятие потока инициализации */
_initThread.Abort();
/* ... */
/* ... */
}
}
}Решение задачи: «Можно ли создать безопасный многопоточный класс»
textual
Листинг программы
if( _state != DeviceCommunicatorState.idle ) return; // возможно долгая операция _state = DeviceCommunicatorState.ready;