Sunday, July 6, 2014

Testing Observables using NUnit/Moq in MVVM

Mock->setup a function must run for each parameter change.
Obs.Create take in IObser and return IDispoable. So next a Subject to call OnNext.
Note that Subject.sub(Obr) will allow OnNext to stream out Obs.
Finally, testSchedule must advance to see data coming out.

Mock _mockT= Mock;
_VMController = new(_mockT.Object, ...);
[Test] public void IdChanged() {
   Id = new Hashset(){guid};
   _mockT.Setup(p=>ObserveData(Id)
   .Return(GenerateObs(id:Id, data: 100.01));
   Assert.AreEqual(_VMController.ViewModel.DataCollecton.Count,1);
}
IObs<PT> GenerateObs(string id="", double? data=null,DateTime logicalDate=null) {
Data data = new (...);
return Observable.Create(obsr=>{   // Func<IObserver,IDispoable>
var s = new Subject<Data>();
   s.subscribe(obsr);
   onNext<Data>(s,data);
return s;
});
}
void onNext<T> (IObserver obr, T data)
{
  obr.OnNext(data);
  _testSchedule.AdvancedBy(250ms);
}

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

    



Tuesday, April 22, 2014

Generate Observables


    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtStart = DateTime.Now;
            var txns = GenerateObservable<Transaction>(3, dt => new Transaction() { id = "txn " + dt.ToString() }, 3, dt => dt < dtStart.AddSeconds(120));
            var bsds = GenerateObservable<Transaction>(1, dt => new BondStaticData() { id = "bsd " + dt.ToString() }, 3, dt => dt < dtStart.AddSeconds(10));

            txns.CombineLatest(bsds,(t,b)=> t.id+" "+b.id).Subscribe(s=>Console.WriteLine(s));

            Console.ReadLine();
        }

        static IObservable GenerateObservable<T>(int seconds4Iteration, Func<DateTime,T> newT, int nextInSeconds,Func<DateTime,bool> continuation)
        {
            DateTime dtStart = DateTime.Now;
            return Observable.Generate(dtStart, continuation, dt => dt.AddSeconds(seconds4Iteration), newT, dt => TimeSpan.FromSeconds(nextInSeconds));
        }
    }

Tuesday, March 18, 2014

Await a Task Completion Source Task for Async Data




The following can be modified to use yield return and observables
 private async void Button_Click(object sender, RoutedEventArgs e)
        {
            await Test();
        }
        Task Test()
        {
            WebClient w = new WebClient();
            return w.DownloadStringTaskAsync("");
        }

        Task RunCodeBlockAsync()
        {
            var tcs = new TaskCompletionSource();
            WebClient w = new WebClient();
            w.DownloadStringCompleted +=
                (_, args) =>
                {
                    tcs.SetResult(args.Result);
                };
            return tcs.Task;
        }

Thursday, November 14, 2013

Context Menu style must be applied to MenuItem Level by ItemContainerStyle to avoid delegate command bind to the same target



Context Menu style must be applied to MenuItem Level by ItemContainerStyle

Using TextBox.ContextMenu will create two instances of the style s1 so it will not bind only one textbox by Multiple binding.

        <TextBox HorizontalAlignment="Left" Height="30" Margin="10,554,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="211" Name="tb1" >
            <TextBox.ContextMenu>
                <ContextMenu ItemsSource="{Binding Mode=OneWay,Path=SelectorData}" ItemContainerStyle="{StaticResource s1}"></ContextMenu>
            </TextBox.ContextMenu>
        </TextBox>

            <Style TargetType="MenuItem" x:Key="s1">
                <Setter Property="ItemsSource" Value="{Binding SubSelectorData}"></Setter>
                <Setter Property="Header" Value="{Binding Name}"></Setter>
                <Setter Property="Tag" Value="{Binding ReturnValue}"></Setter>
                <Setter Property="Command" Value="{Binding SelectorCommand}"></Setter>
                <Setter Property="CommandParameter">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource multiSenderTarget2CmdParamConv}">
                            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type TextBox}}"></Binding>
                            <Binding RelativeSource="{RelativeSource Self}"></Binding>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
           
            </Style>


public List<SelectorData> SelectorData { get; set; }

            SelectorService svc = new SelectorService();
            svc.SelectorCommandAll = new DelegateCommand<object>((p) =>
            {
                Tuple<object, object> t = p as Tuple<object, object>;
                TextBox tb = t.Item1 as TextBox;
                MenuItem mi = t.Item2 as MenuItem;
                tb.Text = mi.Tag.ToString() + ";" + mi.Header.ToString();

            });

    public class MutipleSenderTargetToCommandParameterConverter : System.Windows.Data.IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (values.Length == 1) return new Tuple<object>(values[0]);
            if (values.Length == 2) return new Tuple<object, object>(values[0], values[1]);


        <Style x:Key="ssOnlyOneInstanceNotWorking" TargetType="{x:Type TextBox}" >
            <Setter Property="TextBox.ContextMenu" >
                <Setter.Value>
                    <ContextMenu ItemsSource="{Binding Mode=OneWay,Path=SelectorData}" ItemContainerStyle="{StaticResource s1}"></ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>


    public class SelectorData
    {
        public string Name { get; set; }
        public List<SelectorData> SubSelectorData { get; set; }
        public bool HasSubSelectorData { get; set; }
        public int Level { get; set; }
        public DelegateCommand<object> SelectorCommand { get; set; }
        public string ReturnValue { get; set; }
    }