2012-01-08 74 views
-1

我想將RX的一些C#轉換爲F#代碼。 以下是C#代碼:F#RX將異步模式轉換爲可觀察序列

Stream inputStream = Console.OpenStandardInput(); 
var read = Observable.FromAsyncPattern<byte[], int, int, int>  
    (inputStream.BeginRead, inputStream.EndRead); 
byte[] someBytes = new byte[10]; 
IObservable<int> source = read(someBytes, 0, 10); 
IDisposable subscription = source.Subscribe(
         x => Console.WriteLine("OnNext: {0}", x), 
         ex => Console.WriteLine("OnError: {0}",         ex.Message), 
         () => Console.WriteLine("OnCompleted")); 
Console.ReadKey(); 

以下是我在F#代碼:

#light 
open System 
open System.Collections.Generic 
open System.Linq 
open System.Reactive 
open System.Reactive.Linq 
open System.Reactive.Subjects 
open System.Threading 
open System.IO 

let inputStream: Stream = Console.OpenStandardInput() 
let read = Observable.FromAsyncPattern<byte[], int, int, int>(inputStream.BeginRead, inputStream.EndRead) 
let someBytes: byte[] = Array.create 10 (byte(0)) 
let source: IObservable<int> = read(someBytes, 0, 10) 

let subscription:IDisposable = 
       source.Subscribe((fun x -> printfn "OnNext %A" x), 
           (fun ex -> printfn "OnError %A" ex.Message), 
           (fun _ -> printfn "OnComplete")) 
Console.ReadKey() |> ignore 

,但我得到了以下編譯器錯誤:

Error 1 No overloads match for method 'FromAsyncPattern'. The available overloads are shown below (or in the Error List window).

Error 2 Possible overload: 'Observable.FromAsyncPattern<'TResult>(begin: Func<AsyncCallback,obj,IAsyncResult>, end: Func<IAsyncResult,'TResult>) : Func<IObservable<'TResult>>'.

Error 3 Possible overload: 'Observable.FromAsyncPattern<'T1,'TResult>(begin: Func<'T1,AsyncCallback,obj,IAsyncResult>, end: Func<IAsyncResult,'TResult>) : Func<'T1,IObservable<'TResult>>'.

看來編譯器F#沒有認識到重載,但我不知道如何讓F#編譯器更聰明地完成它的工作。 請給我看你的代碼。 謝謝,祝你週末愉快。 John

回答

3

問題是FromAsyncPattern的參數是代表(類型Func<...>)的代表而不是F#函數(類型_->_)。因此,您不能只傳遞一個方法(如inputStream.BeginRead),但需要傳遞一個顯式函數(例如fun a b c d e -> inputStream.BeginRead(a,b,c,d,e))或顯式構造一個委託(例如System.Func<_,_,_,_,_,_>(fun a b c d e -> inputStream.BeginRead(a,b,c,d,e)))。

在你的情況,我認爲

let read = Observable.FromAsyncPattern(
      (fun a b c d e -> inputStream.BeginRead(a,b,c,d,e)), 
      fun r -> inputStream.EndRead r) 

應該工作。

+0

嗨,你能告訴我你的解釋完整的代碼,所以我會更好地理解它。謝謝! – 2012-01-08 17:26:58

+0

@JohnJohn - 我已經添加了一個完整的示例,但我的計算機上沒有RX來驗證它是否可行。 – kvb 2012-01-09 14:41:21

+0

kvb:謝謝,我根據你的建議更改了我的代碼。 但我得到了以下編譯器錯誤: 錯誤:無法從此代碼位置訪問成員或對象構造函數'FromAsyncPattern'取2個參數。方法'FromAsyncPattern'的所有可訪問版本都帶有2個參數。 – 2012-01-10 19:30:23