映射x2:使用线程来完成工作

时间:2012-02-29 19:41:51

标签: .net f#

尝试通过线程进行异步编程。首先,我尝试一个简单的案例:并行映射列表。到目前为止的代码如下:

let doWork (x:('a -> string)) (y:'a) (z:string ref) (finished:bool ref) =
    ThreadPool.QueueUserWorkItem( fun _ -> z:= x y
                                           finished:= true)
let dualmap (x:'a list) (y:'a -> string) (z:string -> 'b) = 
    let acc = []
    let rec dual (x:'a list) (y:'a -> 'b) (acc:'b list) = 
            match x with
            | [] -> acc
            | [i] -> (y i)::acc
            | i::j::tl -> let un      = ref ""
                          let deux    = ref ""
                          let unfin   = ref false
                          let deuxfin = ref false
                          doWork y i un   unfin   |> ignore //case i
                          doWork y j deux deuxfin |> ignore //case j
                          while not(unfin)||not(deuxfin) do Thread.Sleep(0)
                          let uno  = z !un
                          let dos  = z !deux 
                          dual tl y (dos::(uno::acc))
    dual x y acc

但是,我不确定如何让线程完成工作,因为它们似乎是obj -> unit而不是'a -> 'b'a -> 'b -> 'c,这就是我需要的。< / p>

相反,我必须确保我知道如何将每个对象转换为字符串,然后将其转换回来。似乎必须有一种更简单的方法来做到这一点?

3 个答案:

答案 0 :(得分:2)

你想做这样的事吗?

let asyncMap f items = 
  let rec loop acc items =
    async {
      match items with
      | [] -> return List.rev acc
      | [x] -> 
        let! a = f x
        return! loop (a::acc) []
      | x::y::rest ->
        let! a = f x
        let! b = f y
        return! loop (b::a::acc) rest
    }
  loop [] items

答案 1 :(得分:2)

是否要使用StartChild并行运行,以便返回静态类型的值?

http://msdn.microsoft.com/en-us/library/ee370511.aspx

答案 2 :(得分:2)

不要使用低级Thread API(这很乏味且容易出错);使用任务并行库(System.Threading.Tasks中的类)或PLINQ(System.Linq中的名称中有Parallel的类)。以下是后者的一个例子:

open System.Linq

let pmap (x:_ seq) (f:'a -> 'b) =
    x.AsParallel().AsOrdered().Select(f).AsEnumerable()