William Kempf

Back to Profile: wkempf


  • Looking Ahead to C# 7 with Mads Torgersen

    @AnilApex: There's no such thing as a "single core" or "multi-core" program. Any multi-threaded program will use as many cores as it can. And there's no magic a compiler can do to turn a single threaded program into a multi-threaded program.

    @MadsTorgersen What happened to the contract ideas? Are we going to go yet another release without DbC support in the language? Why? Even the C++ committee is looking into this. For others, yes I'm aware of the Code Contracts framework from the research group, but there are many reasons why that just doesn't cut it. Chief among them is that no "third party" or "add on" solution is going to work... we need contract usage to be pervasive, which means it must be part of the language. The IL rewriting solution is also problematic... we need contract's implemented at the compilation phase.

  • The Future of WPF

    @Max: Silverlight is dead. It's life was stretched out a little with Windows Phone (though that's a Silverlight of a different color), but even there they've moved on. Don't expect any news about Silverlight.

  • CShell, the open source C# REPL IDE

    @Xpndable: Yeah, the fact that the REPL is a PowerShell REPL and not a C# REPL. Both may be using the .NET framework, but usage patterns are quite different. You can't learn C# by programming in VB.NET, which is really the equivalent of what you're suggesting.

  • Remember...

    Improper how? You actually created a new account just to troll this post?

  • Tip 3: Wrap events up in ​Task-​returning APIs and await them

    When I say API I'm not interested in how it's implemented, so all of the talk about FromEventPattern is static. What I'm talking about is the public API, in this case the signature of WhenReadingChanged (again, I'm renaming so the name doesn't give an indication of IObservable or Task). The question is whether WhenReadingChanged should return a Task or an IObservable. I'm maintaining it should return an IObservable.

    You are, however, correct when you ask if my point is that ReadingChangedObservable could have been used identically in both the async version and the Rx version. That's precisely the point. By defining your API (ReadingChangedObservable / ReadingChangedAsync / WhenReadingChanged / whatever) to return an IObservable you can use it with either Rx composition (appropriate when composing streams) or with async/await (appropriate when composing the "next" event as was done in several examples here). Contrast this with returning a Task. If you do that, you've lost the stream and can only compose with async/await (actually, we're totally glossing over composing with ContinueWith... the key is that await works not on Task but on awaitables, and both Task and IObservable are awaitables). IMHO, nothing is gained by returning Task, but a lot is lost, so you simply shouldn't return Task here.

  • Tip 3: Wrap events up in ​Task-​returning APIs and await them

    You can't change the framework. By API, I mean *your* API. In this case, the WhenReadingChanged (or name of your choice) extension method. You still seem to be missing the crux of this, though. "(2) whether we should implement our logic using RX combinators or language combinators" sure seems to be missing my point. By returning an IObservable instead of a Task I have not limited you to Rx combinators. You can still use async/await to compose. What I've done is made the API (WhenReadingChanged) usable by both language and Rx combinators.

    The guidelines as I see how they should be followed:

    1. If the legacy event is part of an EAP implementation, wrap it with a Task, otherwise wrap it with an IObservable.

    2. When composing, if you're composing streams you'll use Rx combinators, otherwise you should prefer language combinators using async/await.

    (2) is a little oversimplified, so there's likely exceptions to be found, but 1 seems pretty obvious and I see no room for variation.

  • Tip 3: Wrap events up in ​Task-​returning APIs and await them

    BTW, your StartShakeWatcher example violates one of the tenets from earlier in this series. Async void methods and delegates should only be used for top level event handlers. One of the reasons for this is to allow the API to be composable, but once you take that into consideration your original IObservable implementation is probably the better implementation. *shrug* Regardless, I believe my point still stands and streams of events should be modeled at the API level with IObservable and not Task.

  • Tip 3: Wrap events up in ​Task-​returning APIs and await them

    Let's change the name in your example to just WhenReadingChanged so we can use the same name for both the Task solution and the IObservable solution. Now realize that an IObservable is an awaitable and you're first example works whether WhenReadingChanged returns a Task or an IObservable. Returning an IObservable is more appropriate, however, because the event is recurring. IObservable can handle composition of recurring event streams, while Task cannot. So returning a Task limits usage, while returning IObservable does not, and both provide the same usability in your scenarios where you're using a Task.

    // Shake detection using async (from a stream of Accelerometer.ReadingChangedEventArgs)
    public async void StartShakeWatcher(Accelerometer accel) {
        var t = DateTime.Now;
        while (true) {
            // Doesn't matter if WhenReadingChanged returns a Task or an IObservable, this works the same.
            var e = await accel.WhenReadingChanged();
            if (Math.Pow(e.AccelerationX, 2) + Math.Pow(e.AccelerationY, 2) < 1.1) continue;
            if ((DateTime.Now - t).Milliseconds < 200) Shake(this, null);
            t = DateTime.Now;

  • Tip 3: Wrap events up in ​Task-​returning APIs and await them

    This set of screen casts has been interesting, but this is the first one I've got serious problems with. At a conceptual level, I think you're abusing Task. Events typically are expected to be fired more than once. The only real exception to this is an event that's part of the EAP pattern. You're StoryBoard example is an EAP scenario, and there I have no problems with replacing that pattern with the TAP pattern. In fact, the EAP pattern should be considered harmful at this point, and TAP should be used for all new code and all legacy async code should be wrapped. All of you other examples, though, aren't part of the EAP, and as such are expected to be raised multiple times. For this, Task is the wrong solution. IObservable is the correct solution, and Rx observables are awaitable.

    At an implementation level, you also have problems. Your TaskCompletionSource pattern fails to handle exceptions.

  • Microsoft DevRadio: Reactive Extensions for Windows 8

    Is there a reason you mention iTunes and RSS but not Zune/Xbox/whatever-it's-called-today in each of the entries here? Or why there appears to only be an Audio subscription there?

  • Git Support Added to Visual Studio and TFS

    Is there a dependency on Team System in order to use GitHub from Visual Studio?

    If I've read the linked pages correctly, no. You can create just a local Git repository when creating a project, and you can clone a project from GitHub or anywhere else.

  • Ping 160: Sinofsky, WP celebrity ads, Nook app, Xbox anniversary

    Was that a Surface Skateboard by the fridge? Wink

    I'm actually disappointed with the B&N and MS collaboration so far. A Windows 8 app, but no WP8 app? The Windows 8 app isn't all that spectacular, either, in comparison to the Kindle app (I'm a NOOK owner, and live in that ecosystem, so I'm not playing fan boy here). Then the most recent NOOK tablet was still an Android based system. Doesn't seem like much of a collaboration to me.