Sunday, June 29, 2014

Use TPL/ TaskCompletionSouce to Implement DownloadAsync

Using Task create non-blocking, TaskCompletionSource SetResult helps send result accross
        static void Main(string[] args)
        {
            Task<string> t = DownloadAsync();
            Console.WriteLine("Do some other work while wating for Async Donwload");
            Thread.Sleep(3000);
            Console.WriteLine("other work done");
            t.ContinueWith((t1) => { Console.WriteLine(t1.Result); });
            // Task.WaitAny(new[] { t }); Wait =Readline to keep program running
           // Console.WriteLine(t.Result);
            Console.ReadLine();
        }

        static Task DownloadAsync()
        {
            TaskCompletionSource<string> ts = new TaskCompletionSource<string>();
            string i="";
            Task.Factory.StartNew(()=> { i = DownloadSync(); }).ContinueWith((t)=>
            { ts.SetResult(i); });
            return ts.Task;

        }
        
        static string DownloadSync()
        {
            Thread.Sleep(5000);
            return "Data";
        }

Saturday, June 28, 2014

Convert Property Change to Observable

INPC enable binding V <-> VM and need ICommand to execute request to Server side. It is interesting to see if Observables in Rx running on
a TaskPoolScheduler can do the same as Delagete or Relay Command. Both FromEventPattern and CLR event should work

    public class ViewModel : INotifyPropertyChanged
    {
        public string Cusip { get; set; }
        public double Ask { get;set; }

        public event PropertyChangedEventHandler PropertyChanged;

        public IObservable<Tuple<T, string>> OnSubmitChanges<T>(Expression<Func<ViewModel, T>> exp)
        {
            MemberExpression me = exp.Body as MemberExpression;
            string n = me.Member.Name;
            Func<ViewModel, T> f = exp.Compile();
            T i = f.Invoke(this);
            return Observable.Return(new Tuple<T,string>(i,n));
        }

        public ViewModel()
        {
            PropertyChanged += ViewModel_PropertyChanged;
//  Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(hh => hh.Invoke, h => this.PropertyChanged += h, h => this.PropertyChanged -= h)
                .Subscribe((e) => { ViewModel_PropertyChanged(this, e.EventArgs); });
        }

        private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
// From Event Pattern does not need subscribe again. Direct call Server side is enougth.
            if (e.PropertyName == "Cusip")
                OnSubmitChanges(vm => vm.Cusip).Subscribe((i) => { Console.WriteLine("Call IVMController->IModObsAdapter->IModObsTransport->QueueAsObserver " + i); }); //459200-10-1 //912828NB2
            if (e.PropertyName == "Ask")
                OnSubmitChanges(vm => vm.Ask).Subscribe((i) => { Console.WriteLine("Hit bid lift offer " + i); });

        }
    }


        private static void TestConvertPropChangeToObservable()
        {
            ViewModel v = new ViewModel();
            v.Cusip = "912828NB2";
            v.OnSubmitChanges(vm => vm.Cusip).Subscribe((i) => { Console.WriteLine("Call IVMController->IModObsAdapter->IModObsTransport->QueueAsObserver " + i); }); //459200-10-1 //912828NB2
            v.Ask = 98.23;
            v.OnSubmitChanges(vm => vm.Ask).Subscribe((i) => { Console.WriteLine("Hit bid lift offer " + i); }); 

        }

Sunday, June 22, 2014

F# Async through Agent= inbox as Queue

Agent are mailbox and can run async block, similar to run a async block inside a function.




open System
open System.Net 
open Microsoft.FSharp.Control.WebExtensions 
open System.Diagnostics 
open System.IO 


let urlList= ["cnn" , "http://www.cnn.com"
              "china", "http://www.china.com"
             ]


let fetch( url :string) = 
        let uri = new Uri(url)
        let c = new WebClient()
        let html =c.DownloadString(uri)
        printfn "%s" html

let fetchAsync(n: string, url :string) = 
    async {
        let uri = new Uri(url)
        let c = new WebClient()
        let! html =c.AsyncDownloadString(uri)
        printfn "%s" html
    }

let runAsync() =
    urlList 
    |> Seq.map fetchAsync
    |> Async.Parallel 
    |> Async.RunSynchronously 

let runSync() = 
    "http://www.cnn.com"
    |> fetch


let s= new StreamWriter("c:\working\1.txt",true)
s.AutoFlush <-true
let agent =
    MailboxProcessor.Start( fun inbox ->
     async {    while true do
                let! msg =inbox.Receive()
               // fetch(msg)
                s.WriteLine(DateTime.Now.ToString()+ " "+msg);
                })


[]
let main arg =
    runSync()
    fetch("http://www.cnn.com")
    
    runAsync() |> ignore
 
    agent.Post("http://www.cnn.com")
    agent.Post("http://www.china.com")
    agent.Post("http://www.goolge.com")
    agent.Post("http://www.fb.com")
    let mutable b=true
    let mutable n=1
    Console.ReadLine() |> ignore
    while b do
        n<-n+1
        if n>1000 then
            b <-false
        agent.Post(n.ToString())

    Console.ReadLine() |> ignore
    s.Close()
    0