2016-06-29 3 views
0

Я пытаюсь правильно обрабатывать файлы в веб-приложении. При загрузке файла я запирать на объект:Как правильно синхронизировать эти потоки?

lock(lockObject) 
{ 
    //Download file here. 
} 

так, что если тот же файл собирается быть удален из другого потока, в то время как в середине загрузки, «удалить» поток ожидает для «загрузки» резьба до конца:

lock(lockObject) 
{ 
    //Delete file here. 
} 

Это работает, но представляет собой еще одну проблему: два потока не могут загрузить файл одновременно.

Как я могу сделать это так, чтобы несколько потоков могли одновременно запускать «загружаемый» код, но в то же время не разрешать никому запускать код «удалить» до тех пор, пока потоки «загрузки» не будут выполнены?

Я знаю, что ответ находится где-то в классе Monitor, но я не уверен, как его снять.

+0

Это не ясно, как загрузить темы распространяют задачу загрузки одного файла ... однако, что есть, в любом случае, вы, вероятно, менеджер нить удерживать блокировку и распределять работу по его пулу потоков каким-то образом. Таким образом, поток delete может ждать блокировки, хранящейся в потоке менеджера, но поток менеджера может делать все, что захочет, с пулом работников. Если вы не имеете в виду что-то еще по вашему вопросу? Это не очень ясно ... более подробная информация поможет. –

+0

@J ... Я не уверен, что вы спрашиваете. Код загрузки выполняется обычными потоками из пула потоков, предоставленными .NET, когда пользователь делает запрос HTTP. Код удаления запускается заданием очистки на стороне сервера, которое запускается каждый час. В любом случае, я не думаю, что это должно иметь значение. – AxiomaticNexus

+0

Нет, ответ не в классе «Монитор». Вы можете использовать [ReaderWriterLockSlim] (https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim (v = vs.110) .aspx), чтобы разрешить несколько потоков загрузки, но принудительно удалить thread, чтобы дождаться, пока все потоки загрузки будут выполнены. Однако мне непонятно, почему вы хотите удалить файл сразу после его загрузки или как вы собираетесь иметь два разных потока, загружающих один и тот же файл. –

ответ

1

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

ReaderWriterLockSlim theLock = new ReaderWriterLockSlim(); 

void Delete(filename) 
{ 
    theLock.EnterWriteLock(); 
    try 
    { 
     // do delete stuff here 
    } 
    finally 
    { 
     theLock.ExitWriteLock(); 
    } 
} 

void Download(filename) 
{ 
    theLock.EnterReadLock(); 
    try 
    { 
     // do delete stuff here 
    } 
    finally 
    { 
     theLock.ExitReadLock(); 
    } 
}   
Смежные вопросы