2013-04-11 2 views
2

Я сейчас смотрел на себя слепо, поэтому, пожалуйста, помогите.То же самое значение возвращается из метода асинхронного вызова

Когда я вызываю этот метод дважды, внутри цикла он возвращает те же значения. Зачем ?

public async Task<int> RollDice() { 
    var rnd = new Random(); 
    var selected = 0; 

    await Task.Run(() => { 
     selected = rnd.Next(1, 6); 
     }); 

    return selected; 
} 

ответ

6

Вы должны инициализировать Random объект вне метода, чтобы предотвратить его инициализации снова и снова с тем же семени, и поэтому возвращаются одни и те же значения.

Важно отметить, что LukeH правильно добавляет в комментарии, что класс System.Random - это , а не потокобезопасный и не должен использоваться совместно между задачами в отдельных потоках.

+0

doh, конечно :) – danielovich

+2

Правильно, но ... будьте осторожны, что 'System.Random' не является потокобезопасным, поэтому совместное использование одного экземпляра между несколькими задачами threadpool (через' Task.Run') не является хорошая идея. – LukeH

+0

@ LukeH Спасибо, я отредактировал свой ответ соответственно. –

2

Вы используете два экземпляра класса Random. Используя parameterless constructor, генератор случайных чисел высевается с использованием значения, основанного на системных часах.

Это означает, что если вы создаете два экземпляра Random вскоре после друг друга, они будут инициализированы с использованием того же значения, потому что системные часы имеют конечное разрешение. Наличие того же семени означает, что эти два экземпляра будут иметь такую ​​же последовательность результатов.

Некоторые Googling показали, что с помощью Random кросса-нити может привести к его поломке и возвращает бесконечную последовательность нулей, поэтому если у вас есть мульти-нить этой конкретной части кода, вы можете захотеть взглянуть на this article о том, как для создания однопоточной безопасной версии класса Random.

Смежные вопросы