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 TaskDownloadAsync() { 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"; }
Sunday, June 29, 2014
Use TPL/ TaskCompletionSouce to Implement DownloadAsync
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
Subscribe to:
Posts (Atom)