У меня небольшое количество задач, и я хочу использовать Task.WaitAll
для их параллельного запуска.Вот что у меня сейчас:
type System.Threading.Tasks.Task with
static member WaitAll(ts) =
Task.WaitAll [| for t in ts -> t :> Task |]
let processf p fs =
let rand = Random ()
let ts = fs |> Array.map (fun f -> Task.Factory.StartNew(fun () -> p(f, rand)))
Task.WaitAll(ts)
ts |> Array.map (fun t -> t.Result)
Проблема в том, что Random
не является поточно-ориентированным (класс Random
выбран только для иллюстрации).Как я могу создать объект для каждого потока, а не создать объект для каждого Task
, что расточительно?
РЕДАКТИРОВАТЬ:
Использование ThreadStatic
, как у Брайанаи предложения Даниэля - хороший подход, особенно с фабричным классом.Однако я предпочитаю ThreadLocal
, предложенный Ридом и Томасом, потому что это выглядит проще.Я согласен, что использование мастера Random
немного сложнее.Ниже приведено смешанное решение, которое я оставлю для дальнейшего использования:
let processf p fs =
use localRand = new ThreadLocal<_>(
fun() -> Random(Thread.CurrentThread.ManagedThreadId))
let ts = fs |> Array.map (fun f ->
Task.Factory.StartNew(fun () -> p(f, localRand.Value)))
Task.WaitAll(ts)
ts |> Array.map (fun t -> t.Result)