Multithreading 如何在多线程f中实现函数内锁定#

Multithreading 如何在多线程f中实现函数内锁定#,multithreading,f#,locking,threadpool,Multithreading,F#,Locking,Threadpool,我创建了一个名为tickets的可变列表,其中包含类型Ticket。 我还有一个bookSeat函数,它模拟预订座位。因为F#list类型是不可变的,所以我的bookSeat函数总是返回一个新的、修改过的、机票列表的副本 open System open System.Threading type Ticket = {seat:int; customer:string} let mutable tickets = [for n in 1..10 -> {Ticket.seat = n;

我创建了一个名为tickets的可变列表,其中包含类型Ticket。 我还有一个bookSeat函数,它模拟预订座位。因为F#list类型是不可变的,所以我的bookSeat函数总是返回一个新的、修改过的、机票列表的副本

open System
open System.Threading

type Ticket = {seat:int; customer:string}
let mutable tickets = [for n in 1..10 -> {Ticket.seat = n; Ticket.customer = ""}]
let bookSeat _ =
    Console.WriteLine("Enter seat number: ")
    let seatNo = int(Console.ReadLine())
    Console.WriteLine("Enter customer name: ")
    let name = string(Console.ReadLine())
    let book seatNo name tickets = 
        tickets |> List.map (fun ticket ->
            if ticket.seat = seatNo then { ticket with customer = name }
            else ticket )    
    tickets <- book seatNo name tickets
这个错误消息很长,我可能会发布一张照片,但我的声誉还不够好


如何在bookSeat函数中成功实现锁定并在运行时在多个线程中调用它?

您的两个线程正在争夺控制台;输入“charles”很可能被执行
seatNo:=int(Console.ReadLine()
赋值的线程使用

我同意关于使用代理/MailboxProcessors的评论,但如果您想使用锁,请锁定提示输入序列:

let bookSeat _ =
  lock (seatNo) (fun _ ->
    Console.WriteLine("Enter seat number: ")
    seatNo := int(Console.ReadLine())
  )
  lock (name) (fun _ -> 
    Console.WriteLine("Enter customer name: ")
    name:= string(Console.ReadLine().ToString()
  )
  ...

此错误与锁定无关。它是在您尝试将字符串转换为数字时产生的。如果您进一步查看堆栈跟踪,您会发现您在代码中进行的调用最终抛出的位置。是只有我还是这种“错误的体系结构”?使用函数式编程的思想部分是为了避免这样的问题…放弃锁并使用代理/邮箱的一些变体不是更好吗?然后是“先到先得”应用,并且由于始终只有一个用户在访问列表,因此不需要锁定。@用户:不仅仅是您。我同意邮箱处理是更好的选择,或者可能是事务性内存。请参阅。事务性内存现在是FSharpX的一部分:
Enter seat number: 
Enter seat number: 5
Enter customer name: charles

Unhandled Exception: System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer & number, NumberFormatInfo info, Boolean parseDecimal).....
let bookSeat _ =
  lock (seatNo) (fun _ ->
    Console.WriteLine("Enter seat number: ")
    seatNo := int(Console.ReadLine())
  )
  lock (name) (fun _ -> 
    Console.WriteLine("Enter customer name: ")
    name:= string(Console.ReadLine().ToString()
  )
  ...