Görev <T> kullanırken, görevin yerine getirilmesi sırasında bir istisna Task.Wait(); F # MailBoxProcessor kullanırken, istisna yutulur ve this question uyarınca açık bir şekilde ele alınması gerekir.Birleştirme Görev <T> ve F # MailboxProcessor özel durum işleme
Bu fark, bir Görev aracılığıyla F # aracısını C# koduna maruz bırakmayı zorlaştırır. Örneğin, bu madde:
type internal IncrementMessage =
Increment of int * AsyncReplyChannel<int>
type IncrementAgent() =
let counter = Agent.Start(fun agent ->
let rec loop() = async { let! Increment(msg, replyChannel) = agent.Receive()
match msg with
| int.MaxValue -> return! failwith "Boom!"
| _ as i -> replyChannel.Reply (i + 1)
return! loop() }
loop())
member x.PostAndAsyncReply i =
Async.StartAsTask (counter.PostAndAsyncReply (fun channel -> Increment(i, channel)))
C# çağrılabilir, ancak istisna C# iade edilmez: Bunun yerine özel durum alma
[Test]
public void ExceptionHandling()
{
//
// TPL exception behaviour
//
var task = Task.Factory.StartNew<int>(() => { throw new Exception("Boom!"); });
try
{
task.Wait();
}
catch(AggregateException e)
{
// Exception available here
Console.WriteLine("Task failed with {0}", e.InnerException.Message);
}
//
// F# MailboxProcessor exception behaviour
//
var incAgent = new IncrementAgent();
task = incAgent.PostAndAsyncReply(int.MaxValue);
try
{
task.Wait(); // deadlock here
}
catch (AggregateException e)
{
Console.WriteLine("Agent failed with {0}", e.InnerException.Message);
}
}
, C# kod sadece task.Wait askıda kalıyor(). F # ajanının bir görev gibi davranmasını sağlamanın bir yolu var mı? Değilse, F # ajanlarının diğer .NET kodlarına maruz kalmasında sınırlı bir kullanım olduğu görülüyor.
Teşekkürler, tam olarak aradığım şey! Kodumun benzer bir dönüşü kullanmasına rağmen, başımın etrafında dönme (e) 'yi yasal bir yapı olarak görmüyorum. "Boom!" ile başarısız. – Akash
'raise'' 'T' döndürme olarak tanımlanır, ancak elbette hiçbir zaman gerçekten geri dönmez. Bu, ifade ifadesinin türüne bakılmaksızın herhangi bir yerde kullanılmasına izin verir. – Daniel
@Akash: Ayrıca şunları yazabilirsiniz: 'Response match res ile Response i -> i | Hata e -> e'yi yükselt. – Daniel