Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#3.0:系统。异常:邮箱的多个等待读卡器连续性_F#_F# 3.0_Mailboxprocessor - Fatal编程技术网

F#3.0:系统。异常:邮箱的多个等待读卡器连续性

F#3.0:系统。异常:邮箱的多个等待读卡器连续性,f#,f#-3.0,mailboxprocessor,F#,F# 3.0,Mailboxprocessor,我正在尝试运行一些MailboxProcessor测试,似乎邮箱扫描()失败,出现“System.Exception:multiple waiting reader continuations for mailbox”。 这发生在Async.Start和Async.StartImmediate等(Async.RunSynchronously也不起作用,因为在初始客户之后只有一个处理器,没有客户) 这是演示代码,它在交互模式下工作: #if INTERACTIVE #r "../packages/

我正在尝试运行一些MailboxProcessor测试,似乎邮箱扫描()失败,出现“System.Exception:multiple waiting reader continuations for mailbox”。 这发生在Async.Start和Async.StartImmediate等(Async.RunSynchronously也不起作用,因为在初始客户之后只有一个处理器,没有客户)

这是演示代码,它在交互模式下工作:

#if INTERACTIVE
#r "../packages/FSharp.Data.2.0.4/lib/net40/FSharp.Data.dll"
#endif
open System
open FSharp.Data
let random = new Random()
let data = FreebaseData.GetDataContext()
let customerNames = data.Commons.Computers.``Computer Scientists``
let nameAmount = customerNames |> Seq.length
// ----

type Customer() =
    let person = customerNames |> Seq.nth (random.Next nameAmount)
    member x.Id = Guid.NewGuid()
    member x.Name = person.Name
    member x.RequiredTime = random.Next(10000)

type Barber(name) =
    member x.Name = name

type ``Possible actions notified to barber`` = 
| CustomerWalksIn of Customer

let availableCustomers = new MailboxProcessor<``Possible actions notified to barber``>(fun c -> async { () })

let createBarber name = 
    Console.WriteLine("Barber " + name + " takes inital nap...")
    let rec cutSomeHairs () = 
        async{
            do! availableCustomers.Scan(function 
                | CustomerWalksIn customer ->
                    async {
                        Console.WriteLine("Barber " + name + " is awake and started cutting " + customer.Name + "'s hair.")
                        // exception also happen with Threading.Thread.Sleep()
                        do! Async.Sleep customer.RequiredTime
                        Console.WriteLine("Barber " + name + " finnished cutting " + customer.Name + "'s hair. Going to sleep now...")
                    } |> Some)
            do! cutSomeHairs ()
            }
    cutSomeHairs() |> Async.StartImmediate

availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)

createBarber "Tuomas";
createBarber "Seppo";

availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
availableCustomers.Post(new Customer() |> CustomerWalksIn)
#如果是交互式的
#r.“./packages/FSharp.Data.2.0.4/lib/net40/FSharp.Data.dll”
#恩迪夫
开放系统
打开FSharp.Data
设random=newrandom()
let data=FreebaseData.GetDataContext()
让customerNames=data.Commons.Computers.``计算机科学家``
名称金额=客户名称|>序号长度
// ----
输入Customer()=
let person=customerNames |>Seq.nth(random.Next name amount)
成员x.Id=Guid.NewGuid()
成员x.Name=个人名称
成员x.RequiredTime=random.Next(10000)
键入理发师(姓名)=
成员x.名称=名称
键入“通知理发师的可能操作”`=
|顾客谈话
让availableCustomers=new MailboxProcessor(趣味c->async{()})
让createBarber名称=
Console.WriteLine(“Barber”+name+“开始小睡…”)
让rec cutSomeHairs()=
异步的{
do!availableCustomers.Scan(函数
|CustomerWalksIn客户->
异步的{
Console.WriteLine(“理发师“+name+”醒了,开始剪“+customer.name+”的头发。”)
//Threading.Thread.Sleep()也会发生异常
do!Async.Sleep customer.RequiredTime
Console.WriteLine(“理发师”+姓名+“芬兰式理发师”+顾客的头发。姓名+”。现在要睡觉了…”)
}|>一些)
做!剪头发()
}
cutSomeHairs()|>Async.StartImmediate
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
创建理发师“托马斯”;
创建理发师“Seppo”;
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
availableCustomers.Post(新客户()|>CustomerWalksIn)
…运行一段时间后,我得到的stacktrace是:

System.Exception: multiple waiting reader continuations for mailbox
   at <StartupCode$FSharp-Core>.$Control.-ctor@2136-3.Invoke(AsyncParams`1 _arg1)
   at <StartupCode$FSharp-Core>.$Control.loop@435-40(Trampoline this, FSharpFunc`2 action)
   at Microsoft.FSharp.Control.Trampoline.ExecuteAction(FSharpFunc`2 firstAction)
   at Microsoft.FSharp.Control.TrampolineHolder.Protect(FSharpFunc`2 firstAction)
   at <StartupCode$FSharp-Core>.$Control.Sleep@1508-1.Invoke(Object state)
   at System.Threading.TimerQueueTimer.CallCallbackInContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.TimerQueueTimer.CallCallback()
   at System.Threading.TimerQueueTimer.Fire()
   at System.Threading.TimerQueue.FireNextTimers()
   at System.Threading.TimerQueue.AppDomainTimerCallback()
Stopped due to error
System.Exception:邮箱的多个等待读卡器继续
在$Control-ctor@2136-3.调用(AsyncParams`1\u arg1)
在$Control。loop@435-40(本次蹦床,FSharpFunc`2动作)
在Microsoft.FSharp.Control.Trampoline.ExecuteAction(FSharpFunc`2 firstAction)中
在Microsoft.FSharp.Control.TrampolineHolder.Protect(FSharpFunc`2 firstAction)上
在$Control。Sleep@1508-1.调用(对象状态)
位于System.Threading.TimerQueueTimer.CallbackInText(对象状态)
位于System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext、ContextCallback回调、对象状态、布尔值preserveSyncCtx)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔保存SyncCTX)
在System.Threading.TimerQueueTimer.CallCallback()中
在System.Threading.TimerQueueTimer.Fire()中
在System.Threading.TimerQueue.FireNextTimers()上
在System.Threading.TimerQueue.AppDomainTimerCallback()中
由于错误而停止
或相同,无螺纹:

System.Exception: multiple waiting reader continuations for mailbox
   at <StartupCode$FSharp-Core>.$Control.-ctor@2136-3.Invoke(AsyncParams`1 _arg1)
   at <StartupCode$FSharp-Core>.$Control.loop@435-40(Trampoline this, FSharpFunc`2 action)
   at Microsoft.FSharp.Control.Trampoline.ExecuteAction(FSharpFunc`2 firstAction)
   at Microsoft.FSharp.Control.TrampolineHolder.Protect(FSharpFunc`2 firstAction)
   at <StartupCode$FSharp-Core>.$Control.-ctor@511.Invoke(Object state)
Stopped due to error
System.Exception:邮箱的多个等待读卡器继续
在$Control-ctor@2136-3.调用(AsyncParams`1\u arg1)
在$Control。loop@435-40(本次蹦床,FSharpFunc`2动作)
在Microsoft.FSharp.Control.Trampoline.ExecuteAction(FSharpFunc`2 firstAction)中
在Microsoft.FSharp.Control.TrampolineHolder.Protect(FSharpFunc`2 firstAction)上
在$Control-ctor@511.Invoke(对象状态)
由于错误而停止

只能从代理的主体调用
邮箱处理器的
接收
扫描
方法。引述:

此方法可在代理体内使用。对于每个代理,最多可以有一个并发读卡器处于活动状态,因此最多只能有一个并发的Receive、TryReceive、Scan或TryScan调用处于活动状态。scanner函数的主体在其执行过程中被锁定,但在异步工作流执行之前解除锁定


因此,您需要以不同的方式构造代码。我没有一个详细的答案,但听起来我的文章在这里可能会有所帮助。

正如Tomas已经指出的,
MailboxProcessor
直接只允许一个读卡器,在异步系统中解决这个问题的一种方法是编写自己的队列或邮箱类型。然而,Tomas在文章中没有提到的一点是,实现新通信原语的另一种方法是使用
Async.FromContinuations
,而不是
MailboxProcessor
AsyncReplyChannel

使用
Async.FromContinuations
的主要优点是,您可以更直接地访问异步机制,并且不必在
MailboxProcessor
AsyncReplyChannel
施加的限制范围内工作。主要缺点是您需要自己确保队列或邮箱线程安全

作为一个具体的例子,Anton Tayanovsky的博客文章包含了一个多读写器同步c的实现