Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

IanG

IanG IanG IanG

Niner since 2004

  • Microsoft Azure Storage – What's New, Best Practices and Patterns

    They mention an example available for download in the talk, but I didn't see a link at the end of the talk, nor do I see one on this page. Where would I find it?

  • Rx Workshop: Schedulers

    Here's an approach that worked for me:

        IObservable<StockQuote> GetQuotes(IScheduler scheduler, IEnumerable<StockQuote> quotes)
        {
            var subject = new Subject<StockQuote>();
            quotes.ToObservable().Subscribe(
                q => scheduler.Schedule(q.Date, () => subject.OnNext(q)));
    
            return subject;
        }
    

    But although CbrAlnK advocates avoiding foreach, doing something more "LINQish", the problem is that this is really just a foreach in disguise. I think the foreach-based solutions are arguably better, because they reveal what's really happening.

    For example, one unfortunate aspect of this whole lab is that it requires the entire schedule to be loaded up before you Run the scheduler. I don't think it's entirely obvious, but a) that code snippet above evaluates the callback (the one that calls scheduler.Schedule(...)) once for every quote inside the call to Subscribe, and b) the example only works because of that synchronous execution of the quotes observable. In other words, this only works because someEnumerable.ToObservable().Subscribe is just an obscure way of writing a foreach loop.

    I was hoping to be able to do something that felt a bit more in keeping with Rx. What I wanted was some way to iterate over a sequence (either in IEnumerable<T> or IObservable<T> form) that was able to select a scheduling time out of that sequence as it generated an observable. So I wanted to be able to write this sort of thing:

        return FeedIntoScheduler(quotes, scheduler, q => q.Date);
    

    The theory there being that I could take an IEnumerable<T> and convert it into an IObservable<T> via a scheduler, where the schedule timings were provided by the Date property of the stock quote. I figured this might be waht Observable.Generate was for, and it sort of it:

        IObservable<T> FeedIntoScheduler<T>(IEnumerable<T> source, IScheduler scheduler, Func<T, DateTime> timeSelector)
        {
            return Observable.Generate(
                new { Enumerator = source.GetEnumerator(), Done = new BoolBox() },
                state =>
                    {
                        if (!state.Done.Value)
                        {
                            bool available = state.Enumerator.MoveNext();
                            if (!available)
                            {
                                state.Enumerator.Dispose();
                                state.Done.Value = true;
                                return false;
                            }
                        }
                        return true;
                    },
                state =>
                    {
                        return state;
                    },
                state => state.Enumerator.Current,
                state => timeSelector(state.Enumerator.Current),
                scheduler);
    
        }   
    // where BoolBox (which enables mutable state in the accumulator, which we need   
    // because Generate rather unhelpfully doesn't fit the enumeration idiom) 
    private class BoolBox
      {
          public bool Value { get; set; }
      }
    
    

    But there's a problem here. The actual work of kicking off the observable is done via the scheduler you pass, and it will pick whatever time the scheduler claims "Now" is. And it turns out that this will crash the historical scheduler provided in the challenge - it's incapable of handling "now" work items. You can fix this by changing the call to AdvanceTo to this:

        if (dt > Now)
        {
            AdvanceTo(dt);
        }
        else
        {
            next.Invoke();
        }
    

    But then a new problem emerges: it turns out the data is in reverse chronological order. So the first item that this schedules is the most recent one, causing the virtual clock to run right to the end, messing things up for the remaining items

    So we have to implement GetQuotes like this:

        IObservable<StockQuote> GetQuotes(IScheduler scheduler, IEnumerable<StockQuote> quotes)
        {
            var quotesInOrder = from quote in quotes orderby quote.Date ascending select quote;
            return FeedIntoScheduler(quotesInOrder, scheduler, q => q.Date);
        }
    

    In conjunction with the FeedIntoScheduler method and the fix to MyHistoricalScheduler, this appears to work. It feels in keeping with the sort of shape I thought I was supposed to be getting for the solution - my GetQuotes builds an IObservable<T> from an IEnumerable<T>, feeding it into a scheduler according to a clearly-defined schedule.

    However, this can't be the "right" solution. For one thing, I had to fix the scheduler to deal with a scenario it wasn't built to deal with. Moreover, this is now very much more complex than the foreach versions originall submitted, and with very little discernable benefit.

    About the one advantage I could think of for this is was that it might work with an infinite sequence - the observable generator is working lazily whereas the foreach versions iterate through the entire thing before even starting the scheduler. For that to work, the enumerable source needs to produce items in order, because the "orderby" query in GetQuotes has to go - orderby can only work on a finite sequence.

    I modified the quote source to feed the items out of the file in asecending date order, and then to just make up an infinite stream of quotes thereafter. And that does actually appear to work. So perhaps this is a scenario for which this much more complex approach is "right".

    I think rab36's solution is in much the same spirit, but using Create instead of Generate. I see that the Create-based solution also ends up requiring the input to be sorted to work correctly.

  • Rx Workshop: Observables versus Events

    The "Download the Challenge" link doesn't work - I'm getting a 404.

  • How To: Use Vista's UAC Feature To Avoid Always Requiring Admin Rights

    "I'm wondering how you made that recording? The video has footage of the UAC desktop -- isn't that meant to be secure and inaccessible to normal applications like screen grabbers -- did you point a camera at your monitor,"

    A bit late to be replying, but better late than never I suppose...

    The video capture was done by a 2nd PC with a video capture card whose input was wired into the VGA output of my laptop.

    So it was slightly higher tech than pointing a camera at the laptop, but it sort of has the same effect: it lets you grab exactly what's on screen, without falling foul of internal security barriers in the machine.


    Ian Griffiths
  • Kevin Schofield - Tour of Microsoft Research, Part I (graphic and developer tool research)

    Usually I play these Channel 9 videos through at 1.4 times normal speed, using the Media Player 'Play Speed Settings' panel.  But it's not letting me do that here.


    It's also not letting my skip to points in the video - it only seems to support playing through sequentially at normal speed.

    Is this deliberate?  Or did you accidently flip some switch on the encoding process too?

  • Bill Hill - Why isn't ClearType on by default in Windows XP?

    I love ClearType, but there's one aspect of it that frustrates me, which is why I was interested to hear that you've been through many different versions of ClearType. I'm intrigued to know if you've fixed my pet peeve with it yet.

    ClearType as featured on the current version of XP does brilliantly for near-vertical features, but when it comes to near-horizontal features, it does a worse job than plain old 'font smoothing'. I understand that because of the way that ClearType works (and indeed the way that LCD panels are built) it's always going to do a better job of near-vertical stuff. But I don't see why it can't do at least as good a job on the near-horizontal features as normal anti-aliasing can achieve.

    In fact I wrote a little test to illustrate how it's possible to do this:

     http://www.interact-sw.co.uk/iangblog/2004/03/10/iantype

    (I'm not doing a great job on the colour filtering in this example, but it does illustrate what I mean about near-vertical features.) I'd be interested to know if anything like this might be coming to Longhorn. And if not, I'm interested to know if you've considered it, and came up against reasons why you just can't do this.