Я использую DLL-форму для внешнего поставщика. Эта DLL не является потокобезопасной, она фактически останавливается с сообщением об ошибке, если я пытаюсь вызвать его методы из разных потоков. И я использую DLL из более крупной структуры, использующей больше потоков, обращающихся к DLL. Нити не активны одновременно, нет риска условий гонки.
Итак, вопрос: Каков простой способ преодолеть это? Я начал создавать оболочку, которая работает в одном специальном потоке для этого, который никогда не прерывает использование ManualResetEvent, waitOne и событий. Но прохождение событий не делает трюк. Как заставить dll полагать, что он используется только из одного потока?
Я рекомендую кодировать класс-оболочку для вашей dll.
Если вы используете.net 4+, вы можете просмотреть специализированные планировщики задач. Специально это: http://blogs.msdn.com/b/pfxteam/archive/2010/04/07/9990421.aspx
Если вы этого не сделаете, вы можете применить тот же принцип без TPL. Это будет немного больше работы.
Вызовите каждое выделение из этой DLL через задачи, запланированные на StaTaskScheduler.
Ваши вызовы dll должны быть прекрасными;)
Редактировать:
Я думаю, что код должен выглядеть так:
public class NotThreadSafeClass
{
public int SomeMethod(string x, int y)
{
return 3;
}
}
public class ThreadSafeWrapper
{
private TaskScheduler sta = new StaTaskScheduler(numberOfThreads: 1);
private NotThreadSafeClass old = new NotThreadSafeClass();
public Task<int> SomeMethod(string x, int y)
{
return Task<int>.Factory.StartNew(() => old.SomeMethod(x,y),
CancellationToken.None, TaskCreationOptions.None, sta);
}
}
Я бы продолжал ждать снаружи обертки, если вы в 4+. Кроме того, класс должен быть одноэлементным, чтобы предотвратить множественное создание, которое в конечном итоге приведет к доступу к нему нескольких потоков.