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";
}
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:
Comments (Atom)