Posts about the C# language itself, including use, abuse and features.
Posts about the C# language itself, including use, abuse and features.
It wasn’t very long after my prior update on caching that a friend informed me that the code has a race condition. Yes, the same friend who persuaded me to update it last time. Worse, during a Skype call, we identified code that would outright fail for an independent reason.
After our recent introduction of caching, I had an interesting conversation with a friend about the way I’d written the code. He was persuasive that the approach I’d taken had some significant issues and that it was worth taking the time to address them.
If you’ve been playing around with maintenance screen and the speech integration that we completed last week you may have noticed that there can be a noticeable lag between the time you press a play button and when you hear the speech.
With our speech infrastructure in place, our next step is to hook it up with our existing maintenance screen. This will allow our users to test out pronunciation as they make changes.
Now that we’ve modified our Redux store to support middleware, we have the foundation needed to integrate speech synthesis into the main flow of our application.
Based on the interfaces we defined last time, let’s integrate middleware functionality into our existing Redux store. This will lay the foundation we need for asynchronous speech generation.
At this point in the development of the WordTutor, we need to properly incorporate speech generation into the application. We could hack and glue it into place on top of the existing architecture, or we can integrate it into the existing structure in a clean way.
Saturday, February 29 2020 csharp
Recently a friend of mine noticed some code in a book that was, shall we say, considerably sub-optimal. It’s worth looking at the code to see how both the performance and readability of the code can be easily improved.
For the WordTutor application to work, we need to be able to read words (and letters) out loud to our student. To power the speech synthesis, we’re going to integrate Azure Cognitive Services into the application.
To implement the logging interfaces described earlier, there are some issues we need to consider. There are two different usage patterns we need to support, plus we need to support concurrent use, and avoid code duplication.
After earlier defining our logging interface, some readers posed a few questions about how it would work from a consumers perspective. So before we look at implementation details, let’s look at how we’ll instrument our code and what the output might look like.
As we progress building the WordTutor application, some of the functionality will be a great deal more complex - and that requires a better way to see what’s happening inside the application than we’ve had to date. It’s time to implement some logging.
Following on from our previous post on convention testing we can extend the conventions by considering the standards we want to follow when we write methods on our immutable types.
The Redux architecture we’re using for our application state relies on all our state objects being properly immutable. So far, we’ve relied on nothing more than self-discipline to ensure no mistakes are made. By adding some convention testing to our project, we can enlist some help in avoiding common errors.
If you’ve tried out our application as it stood after last week’s post, you may have noticed that the user experience for modifying a word is a bit suboptimal. After selecting a word, you have to separately press the Modify button. Can we do better?
The existing model class
ModifyVocabularyWordScreen only handles the creation of a new word. We need to modify it to support the modification of an existing word as well.
Here’s an odd warning that came up when I was working on last weeks Code Gardening post:
Continuing our the upgrade process from last time, in this post we’ll explore the changes required to our
Up until this point, we’ve relied exclusively on data-binding for the link between our view-models and our views. While data-binding handles a lot of scenarios well, it doesn’t support buttons, menu items and so on.
With subscriptions wired up to keep our view models updated, we can run our application and start clicking around. When we select a word, we can trace through the flow of messages to see how everything updates. But, it’s easy to crash. Let’s debug that crash and work out how to make the application more robust.
Now that our Redux store supports subscriptions, we can register to update our existing view models, allowing them to automatically stay current as our application state changes. The changes to each will be similar, but with a few variations on the common theme.
One of the problems we currently have is caused by lack of updates - our application model can change without our view-models being notified that the change has happened, leaving our user interface showing stale information. To solve this, we’ll extend our Redux store with subscriptions, to allow each view-models to be proactively notified when things change.
We saw last time that setting up dependency injection for our viewmodels involved a small number of moving parts. The same applies when applying dependency injection to our views, but with a few additional complexities.
Based on the foundation from last time, we can now turn our attention to our view-models. How can we use our dependency injection framework to construct each view model on demand?
To this point, we’ve been able to run each of our screens by hand-coding the necessary object initialization. We could continue this as we move forward, but the complexity would grow with each additional screen we complete. Instead, let’s take the time to configure a dependency injection framework that will take care of the complexity for us.
In addition to the unit tests we’re already writing for each of our core classes, we should also write some integration tests to ensure our types interact properly.
|Restructuring Reducers 13 Jul 2019
|Vocabulary Browser 29 Jun 2019
|Revisiting ViewModelBase 15 Jun 2019
|First Light 08 Jun 2019
|Add Word View 25 May 2019
|Add Word View Model 11 May 2019
|Add Word Screen 04 May 2019
|WPF Projects & ViewModelBase 20 Apr 2019
|Static Analysis 13 Apr 2019
|Redux Store 06 Apr 2019
|Commandline Builds 30 Mar 2019
|Application Model 23 Mar 2019
|Vocabulary Set 16 Mar 2019
|Vocabulary Word 09 Mar 2019
|WordTutor Revisted 02 Mar 2019
|Converting a List to a Queue 23 Feb 2019
|Explicit Interfaces and Delegate Properties 16 Feb 2019
|Extension Methods 19 Jan 2019
|Generating Hash Codes 12 Jan 2019
|The Problem with Equality 05 Jan 2019
|Queue Equality 29 Dec 2018
|Smarter Queue Enumeration 22 Dec 2018
|Queue Enumeration 15 Dec 2018
|Queue Testing 08 Dec 2018
|Creating Branching Nodes 01 Dec 2018
|Two Dual Item Queues 24 Nov 2018
|Simple Queues 17 Nov 2018
|Enqueuing Values 10 Nov 2018
|Dequeuing Values 03 Nov 2018
|Designing the External API 27 Oct 2018
|Introducing the Priority Queue 20 Oct 2018
|A better approach to reflection 13 Oct 2018
|Avoiding Magic Strings 06 Oct 2018
|Capturing Validation Metadata 29 Sep 2018
|Modelling Validation Metadata 22 Sep 2018
|Validation Metadata 15 Sep 2018
|Extending validation with warnings 08 Sep 2018
|Validation recap 25 Aug 2018
|Equality of validation 18 Aug 2018
|Short-circuiting validation 11 Aug 2018
|Aggregation of validation 04 Aug 2018
|Recovery of validation types 28 Jul 2018
|Basic validation 21 Jul 2018
|Why we need better validation 07 Jul 2018
|A question of struct performance 30 Jun 2018
|Equality has Symmetry 17 Mar 2018
|Type Miscellany 05 Mar 2017
|Testing Immutable Types 25 Feb 2017
|Factory Methods 18 Feb 2017
|Queue Concatenation 11 Feb 2017
|Complex Queues 04 Feb 2017
|The Problem with the Simple Queue 28 Jan 2017
|Enumeration of Queues 21 Jan 2017
|Reversing Stacks 14 Jan 2017
|Simple Queues 07 Jan 2017
|Queues 30 Dec 2016
|Stacks Miscellany 22 Dec 2016
|Stack Equality 09 Dec 2016
|Enumerating Stacks 03 Dec 2016
|Stacks 19 Nov 2016
|When (not) to use Var 16 Jul 2016
|Semantic Types Redux 05 Jun 2016
|Semantic Types in C#6 27 May 2016
|Property Enhancements for C# 20 Dec 2015
|Language Extensions for C# 19 May 2014
|When should methods be Static? 09 Oct 2012
|Of Method Naming and more 29 Sep 2012
|Someone needs an intervention 16 Dec 2011
|CallerInfo in C# 5 08 Dec 2011
|Regions in C# 16 May 2011
|Lambda expressions and Block syntax 15 Apr 2011
|Parameter Attributes and more 05 Feb 2011
|Elegant.Data 19 Oct 2010
|Doing less with LINQ 30 Jun 2010
WCF and IList
|Specialist Classes 22 May 2010
|Attack of the Lazy Coder 20 May 2010
|A Discovery in Linq: Lookup 11 Feb 2010
|Co- and Contra-Variance in .NET 3.5 15 Sep 2009
|When to use Var 26 Mar 2009
|Struct Weirdness 11 Feb 2009
|Contravariance and Covariance at last 29 Oct 2008
|Spec# 30 Apr 2008
|Lambda Events 22 Mar 2008
|No longer the C# we knew 21 Mar 2008
|Rare C# 12 May 2007
|Generics in .Net 28 Jan 2004