Я написал метод, который загружает некоторые файлы, и теперь я пытаюсь загрузить его до 5 файлов параллельно, а остальным ждать, пока предыдущие будут завершены. Я использую ManualResetEvent для этого, но когда я включаю часть syncronisation, он больше ничего не скачивает (без этого он работает).Проблема синхронизации с ManualResetEvent
Вот код методов:
static readonly int maxFiles = 5;
static int files = 0;
static object filesLocker = new object();
static System.Threading.ManualResetEvent sync = new System.Threading.ManualResetEvent(true);
/// <summary>
/// Download a file from wikipedia asynchronously
/// </summary>
/// <param name="filename"></param>
public void DoanloadFileAsync(string filename)
{
...
System.Threading.ThreadPool.QueueUserWorkItem(
(o) =>
{
bool loop = true;
while (loop)
if (sync.WaitOne())
lock (filesLocker)
{
if (files < maxFiles)
{
++files;
if (files == maxFiles)
sync.Reset();
loop = false;
}
}
try
{
WebClient downloadClient = new WebClient();
downloadClient.OpenReadCompleted += new OpenReadCompletedEventHandler(downloadClient_OpenReadCompleted);
downloadClient.OpenReadAsync(new Uri(url, UriKind.Absolute));
//5 of them do get here
}
catch
{
lock (filesLocker)
{
--files;
sync.Set();
}
throw;
}
});
}
void downloadClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
//but none of the 5 get here
...Download logic... //works without the ManualResetEvent
}
finally
{
lock (filesLocker)
{
--files;
sync.Set();
}
}
}
я делаю что-то не так?
Он написан с Silverlight 4 для Windows Phone 7.
Edit: Там нет Семафор или SemaphoreSlim в Silverlight 4.
Почему замок, когда вы можете использовать System.Threading.Interlocked.Decrement() '' метод, и т.д.? –
Потому что я также хочу вызвать sync.Set(), и я думаю, что кто-то холодный вызов sync.Set() из другого потока, затем я уменьшаю, некоторые потоки увеличивают и вызывают sync.Reset(), затем я вызываю sync.Set (), и я получаю больше того, что загружает потоки maxFiles. – user182945
Проверьте мой ответ, это то, что вы ищете. Кроме того, использование события сброса в порядке, я просто не вижу необходимости в блокировках. О, и я использую AutoResetEvent, потому что это именно то, что вам нужно здесь. –