Với một chút hack khá khủng khiếp, bạn có thể sử dụng loại MailboxProcessor
từ C# sử dụng async
. Một số khó khăn là loại sử dụng một số tính năng cụ thể F # (đối số tùy chọn là các tùy chọn, chức năng là FSharpFunc
loại, v.v.)
Về mặt kỹ thuật, sự khác biệt lớn nhất là đồng bộ F # được dealyed trong khi C# async tạo một tác vụ đang chạy . Điều này có nghĩa là để xây dựng F # async từ C#, bạn cần phải viết một phương thức mất unt -> Task<T>
và tạo ra Async<T>
. Tôi đã viết một blog post that discusses the difference.
Anwyay, nếu bạn muốn thử nghiệm, đây là một số mã, bạn có thể sử dụng:
static FSharpAsync<T> CreateAsync<T>(Func<Task<T>> f)
{
return FSharpAsync.FromContinuations<T>(
FuncConvert.ToFSharpFunc<
Tuple< FSharpFunc<T, Unit>,
FSharpFunc<Exception, Unit>,
FSharpFunc<OperationCanceledException, Unit> >>(conts => {
f().ContinueWith(task => {
try { conts.Item1.Invoke(task.Result); }
catch (Exception e) { conts.Item2.Invoke(e); }
});
}));
}
static void MailboxProcessor() {
var body = FuncConvert.ToFSharpFunc<
FSharpMailboxProcessor<int>,
FSharpAsync<Unit>>(mbox =>
CreateAsync<Unit>(async() => {
while (true) {
var msg = await FSharpAsync.StartAsTask
(mbox.Receive(FSharpOption<int>.None),
FSharpOption<TaskCreationOptions>.None,
FSharpOption<CancellationToken>.None);
Console.WriteLine(msg);
}
return null;
}));
var agent = FSharpMailboxProcessor<int>.Start(body,
FSharpOption<CancellationToken>.None);
agent.Post(1);
agent.Post(2);
agent.Post(3);
Console.ReadLine();
}
Như bạn có thể thấy, điều này có vẻ :-) thực sự khủng khiếp.
Về nguyên tắc, nó có thể là có thể viết một wrapper C# thân thiện cho các loại MailboxProcessor
(chỉ cần giải nén các bit xấu xí từ mã này), nhưng có một số vấn đề.
Trong F #, bạn thường sử dụng các ký tự đồng bộ đuôi đệ quy để triển khai máy trạng thái trong bộ xử lý hộp thư. Nếu bạn viết cùng một thứ trong C#, cuối cùng bạn sẽ nhận được StackOverflow
, vì vậy bạn cần phải viết các vòng lặp với trạng thái có thể thay đổi.
Hoàn toàn có thể viết tác nhân trong F # và gọi nó từ C#. Đây chỉ là vấn đề hiển thị giao diện thân thiện với C# từ F # (sử dụng phương thức Async.StartAsTask
).
Nguồn
2010-11-02 13:43:58
Bạn có thể sửa liên kết bị hỏng không? – czifro
@czifro, ok. – Benjol