Tag Archives: Windows Store Apps

TaskCompletionSource

I’ve had a couple of problems recently, where I’ve had tasks or asynchronous methods and they don’t quote fit into the architecture that I find myself in. I’d come across the TaskCompletionSource before, but hadn’t realised how useful it was. Basically, a TaskCompletionSource allows you to control when a task finishes; and allows you to do so in a synchronous, or asynchronous fashion. What this gives you is precise control over when an awaited task finishes.

UWP

Consider the following code in UWP. Basically, what this does is execute an anonymous function on the UI thread:

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () => 
{
    await MyAyncFunc();
}
System.Diagnostics.Debug.WriteLine("After MyAsyncFunc");

The problem here is that executing an anonymous async function in the above scenario doesn’t work. However, using the TaskCompletionSource, we can bypass that whole conversation:

TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () => 
{
    await MyAyncFunc();
    System.Diagnostics.Debug.WriteLine("After MyAsyncFunc");

    tcs.SetResult(true);
});
await tcs.Task;

Now the function will return when the the TaskCompletionSource.SetResult has been called.

Event based

The second scenario where this is useful is where you are trying to use an event based architecture within an async / await scenario. The following example is a little contrived, but it does illustrate the point:

    class Program
    {
        private static Timer _tmr = new Timer();
        private static TaskCompletionSource<bool> _tcs;

        static void Main(string[] args)
        {
            var tmr = StartTimer();

            Console.WriteLine("Before wait...");
            tmr.Wait();

            Console.WriteLine("After wait...");
        }        

        private static async Task StartTimer()
        {            

            _tmr.Interval = 3000;
            _tmr.Elapsed += _tmr_Elapsed;
            _tmr.Start();

            _tcs = new TaskCompletionSource<bool>();
            await _tcs.Task;
        }

        private static void _tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            _tcs.SetResult(true);
        }
    }

Potentially, a more real world example of this is when you might want to wrap an API in an async/await.

Control over exactly when a task finishes, and the ability to await async void methods

The final scenario where this can be useful is where you either want to await an `async void` method, or where you have a specific part of a method or process that you want to await.

The following code illustrates how to effectively await an async void method:

    class Program
    {        
        private static TaskCompletionSource<bool> _tcs;

        static void Main(string[] args)
        {
            _tcs = new TaskCompletionSource<bool>();
            BackgroundFunction();

            _tcs.Task.Wait();

            Console.WriteLine("Done");
        }        

        private static async void BackgroundFunction()
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine($"Processing: {i}");
                await DoStuff();
            }
            _tcs.SetResult(true);
        }

        private static async Task DoStuff()
        {
            await Task.Delay(500);
            
        }

    }

Finally, here is a parallel for loop:

        static void Main(string[] args)
        {
            Parallel.For(1, 3, (i) =>
            {
                BackgroundFunction();
            });

            Console.WriteLine("Done");
        }        

Imagine that BackgroundFunction is performing a long running task where a specific condition needs to return control. There are obviously combinations of functions in the TPL (WaitAll, WhenAll, WhenAny and WhenAll), however, these rely on the whole task, or a set of tasks, completing. Again, the below example is contrived, but it illustrates the granular control over the task that you have.

        static void Main(string[] args)
        {
            _tcs = new TaskCompletionSource<bool>();

            for (int i = 1; i <= 2; i++)
            {
                BackgroundFunction();
            }

            _tcs.Task.Wait();            

            Console.WriteLine("Done");
        }        

        private static async void BackgroundFunction()
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine($"Processing: {i}");
                await DoStuff();

                if (i == 7)
                {
                    _tcs.TrySetResult(true);
                    return;                    
                }
            }            
        }

I will re-iterate again, I realise that in the above example, there are better ways to achieve this, and the example is purely for illustration.

Conclusion

Generally speaking, the simplest and most robust code comes from using the task architecture in the way it was designed: that is, use async / await inside a method that returns a Task. I’m not suggesting in this post that the methods I’ve described should replace that; but there are situations where that might not fit.

Aknowledgements

I used the following posts heavily while writing this:

Awaiting the CoreDispatcher
The Nature of TaskCompletionSource
Real life scenarios for using TaskCompletionSource?
Task Parallelism

XAML Translations based on the display size in UWP

Having recently released my latest app into the store, I noticed that some of the buttons didn’t fit well on the phone version. I’d already come across translations for the HTML/WinJS version of Windows 8 apps, but not the XAML version, and not Windows 10 UWP.

You can do this in Expression Blend

First, double click the view file:

transuwp1

In the States window, you’ll then have the ability to create a new VisualStateGroup:

transuwp2

Create the required states; here’s mine:

transuwp3

If you click the lightning bolt to the side of the group, you should get the following:

transuwp4

If you create an adaptive trigger as above, you’ll be able to set the minimum width or height for the change. I’ve set the minimum width for desktop form factor to 500.

Back to code

What that produces for you (remember that you can alt-tab between Blend and VS and it should deal with the changes relatively gracefully) is a piece of code along the lines of this, within the XAML view:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>

            <VisualStateGroup x:Name="VisualStateGroup">

                <VisualState x:Name="Normal">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="500"/>
                    </VisualState.StateTriggers>
                </VisualState>

                <VisualState x:Name="Mobile">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="320"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="tgPlay.(Grid.Column)" Value="0"/>
                        <Setter Target="tgPlay.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandCreateVideo.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandCreateVideo.(Grid.Column)" Value="1"/>
                        <Setter Target="btnCommandClear.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandClear.(Grid.Column)" Value="2"/>
                        <Setter Target="numericUpDown.(Grid.Column)" Value="0"/>
                        <Setter Target="numericUpDown.(Grid.Row)" Value="1"/>
                        <Setter Target="numericUpDown.(Grid.ColumnSpan)" Value="3"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

There’s a number of points here – the first is that you need to name your controls; that’s how they are referenced. If you use Blend and you don’t do this then blend will give them a name; for example, I didn’t give “numericUpDown” a name. If I had another control of the same type then it would just number them.

The second point is the adaptive trigger. 500 and 320 seem to be the generally accepted divisions between desktop and narrow form factor. This approach worked for my specific requirement, although what Blend produces does require some re-work, otherwise it just ends up as a mess.

Handling Input in XNA / MonoGame

This morning I didn’t have internet access and was trying to find this in my notes (which are also my blog posts), and I couldn’t; so purely for my own benefit, the following is a method of handling touch or mouse input in Monogame:

        public void HandleInput()
        {
            ProcessMouseInput();
            ProcessTouchInput();
            ProcessKeyboardInput();
        }

        private void ProcessMouseInput()
        {
            var currentMouse = Microsoft.Xna.Framework.Input.Mouse.GetState();

            if (currentMouse.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
            {
                HandlePressed(currentMouse.Position, _controlledObject);
            }
        }

        private void ProcessTouchInput()
        {
            var currentTouch = Microsoft.Xna.Framework.Input.Touch.TouchPanel.GetState();

            foreach (var touch in currentTouch.Where(t => t.State == Microsoft.Xna.Framework.Input.Touch.TouchLocationState.Pressed))
            {
                HandlePressed(touch.Position, _controlledObject);
            }


        }

        private void ProcessKeyboardInput()
        {
            var currentKeys = Microsoft.Xna.Framework.Input.Keyboard.GetState();
            if (currentKeys.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Left))
            {
                _handler.GoLeft(_controlledObject);

By changing Pressed to Released, you can detect when the mouse button click / touch finished; however, if you hold your finger / mouse button down, it will only return a single result.

Using Asynchronous methods within a Windows Game

The new async / await syntax in .NET 4.5 + makes asynchronous programming really easy. However, there are times when having an assumption of asynchrony can impede you. One such example is programming for games (see my post on why you might want to avoid this).

However, what happens when you want to display a windows message box, or some other action that is asynchronous; See my post on a message box helper for an example.

In my particular case, I was to show a message box asynchronously, and perform a certain action based on the result; however, I don’t want to stop the game, and I don’t want to have to introduce an async / await into the programming model (for reasons in the linked post).

My solution was to use a combination of two, slightly outdated, methods of asynchronous programming: call backs and continuation blocks (strictly speaking, async / await does use continuation blocks behind the scenes admittedly). The following code will attempt to make an in-app purchase from the store:

        internal static async Task<bool> PurchaseCash()
        {
            var result = await Windows.ApplicationModel.Store.CurrentApp.RequestProductPurchaseAsync(PURCHASE);
            return (result.Status == ProductPurchaseStatus.Succeeded);
        }

What that function actually does it not important; however, it needs to be called from within a game loop. Here’s how it is called:

                        Purchase.PurchaseCash().ContinueWith((purchaseTask) =>
                        {
                            purchaseTask.Wait();
                            if (purchaseTask.Result)
                            {
                                App.settings.CashPot.Total += Purchases.Purchase.MORE_CASH_AMOUNT;
                            }

                        });

This will only execute the purchase action if the purchase was successful; it’s completely asynchronous, and it doesn’t affect the main thread. All well and good, but what if, instead of a specific task, we wanted to execute a conditional command; for example: when the purchase is called, we want to turn on a specific feature.

In this case, I decided to use a call back; the method signature looks like this:

        private bool MakePurchase(int cost, Action onSuccess)

And it is called like this:

                    if (!App.settings.Purchase1)
                    {
                        MakePurchase(PURCHASE1_COST, () =>
                        {
                            App.settings.Feature1 = true;
                        });
                    }

Inside MakePurchase, I only call the onSuccess method where the purchase was successful:

                        Purchase.PurchaseCash().ContinueWith((purchaseTask) =>
                        {
                            purchaseTask.Wait();
                            if (purchaseTask.Result)
                            {
                                onSuccess.Invoke();
                            }
                        }

Conclusion

The syntax above is nowhere near as clear and concise as a simple await statement; however, await statements can’t be used outside of an async method and, especially when programming games, that’s not always practical. The other thing that I haven’t mentioned here is exception handling – I may make that the subject of a later post.

Converting an existing Windows Store App to a new one

I recently decided to create a new Windows Store app, that was very similar to one that I’d already created; I decided that it would be a quick task to adapt the existing application and publish under a new name.

Since this is not completely pain free, here are some of the errors and fixes.

The first thing I did was to change the Package name, under the assumption that this would need to be associated with my new application:

StorePackageManifest

When I did so, I got the following error:

The Name attribute of the Identity element in the app manifest must have the Package name value of the selected app: …

I then tried selecting a new test certificate; which results in the following error:

The Publisher attribute of the Identity element in the app manifest must have the value of the Publisher ID value from your developer account: CN=1AAAAAAA-XXXX-YYYY-XXXX-ZZZZZZZZZZZZZZ

Both of these fields are generated when publishing to the store, and I finally realised that the fix was to delete the XML file:

StoreAssociation.xml

When you publish this to the store, these fields will be re-populated, and the StoreAssociation.xml file regenerated.

Playing Media in Windows Universal Apps

I recently had cause to write a universal app that has voice capabilities. Hopefully it will shortly be available on the Windows Store.

Adding voice synthesis, while a seemingly basic task, proved to be anything but. What follows is a series of trials and tribulations that I have overcome in order to bring this app to the public!

The Code

Here’s the basic code to get started.

                var voiceStream = await synth.SynthesizeTextToStreamAsync("Hello");
                
                MediaElement mediaElement = new MediaElement();

                mediaElement.SetSource(voiceStream, voiceStream.ContentType);
                mediaElement.AutoPlay = false;
                mediaElement.Volume = 1;
                mediaElement.IsMuted = false;

                mediaElement.Play();

Windows Phone

The first issue I encountered with Windows Phone was the volume. Having maxed out my laptop speakers, I managed get a faint whimper. What I finally deduced is that, for some reason, when the emulator starts, it starts at half volume. To increase it you have to press the phone’s volume buttons (which I initially assumed were just there for aesthetics. Clearly Microsoft haven’t entirely abandoned skeuomorphism.

Phone

The volume controls are the top right buttons (which I happened to know because I have owned a Windows Phone in the past). Once you press it then a more sensible interface appears and you can change either the ringer volume, or the game volume.

Overtalking

Although the code above does work, try calling the code in a loop (or just twice). What happens is that it doesn’t wait for itself to finish.

What I didn’t realise (until I asked this) was that there are some events which supposedly fire when the media element has finished playing.

                var voiceStream = await synth.SynthesizeTextToStreamAsync(toSay);
                
                MediaElement mediaElement = new MediaElement();

                mediaElement.Loaded += mediaElement_Loaded;
                mediaElement.MediaEnded += mediaElement_MediaEnded;
                mediaElement.MediaFailed += mediaElement_MediaFailed;

                mediaElement.SetSource(voiceStream, voiceStream.ContentType);
                mediaElement.AutoPlay = false;
                mediaElement.Volume = 1;
                mediaElement.IsMuted = false;
                
                mediaElement.Play();

I say supposedly, because when I first tried to capture the events, they did nothing. After a bit of searching, it turns out that the element needs to be part of the visual tree! Which of course makes total sense – an AUDIO media element must be part of the VISUAL tree.

In the Visual Tree

The code below now looks for the media element in the visual tree, and if it can’t find one, adds it. It also uses the TaskCompletionSource object to await the audio stream.

            using (SpeechSynthesizer synth = new SpeechSynthesizer())
            {
                var voiceStream = await synth.SynthesizeTextToStreamAsync(toSay);
                
                MediaElement mediaElement;
                
                mediaElement = this.rootControl.Children.FirstOrDefault(m => (m as MediaElement) != null) as MediaElement;
                if (mediaElement == null)
                {
                    mediaElement = new MediaElement();
                    this.rootControl.Children.Add(mediaElement);
                }
                
                mediaElement.SetSource(voiceStream, voiceStream.ContentType);                
                mediaElement.Volume = 1;
                mediaElement.IsMuted = false;

                var tcs = new TaskCompletionSource<bool>();
                mediaElement.MediaEnded += (o, e) => { tcs.TrySetResult(true); };
                mediaElement.Play();

                await tcs.Task;
                
            }

That works. At least, it works on Windows Phone. Because it uses a media element, I thought putting it on a shared XAML page would work… but it doesn’t. Windows 8.1 just sits there quietly and says nothing.

Windows Store

After much trial and error, it occurred to me (prompted by a comment on the above question) that if the problem was down to a deadlock, then destroying and recreating the control might clear this up.

Amazingly, that did seem to work; the working code is:

            using (SpeechSynthesizer synth = new SpeechSynthesizer())
            {
                var voiceStream = await synth.SynthesizeTextToStreamAsync(toSay);

                MediaElement mediaElement;

                mediaElement = rootControl.Children.FirstOrDefault(a => a as MediaElement != null) as MediaElement;
                if (mediaElement == null)
                {
                    mediaElement = new MediaElement();
                    
                    rootControl.Children.Add(mediaElement);
                }

                mediaElement.SetSource(voiceStream, voiceStream.ContentType);
                mediaElement.Volume = 1;
                mediaElement.IsMuted = false;

                var tcs = new TaskCompletionSource<bool>();                
                mediaElement.MediaEnded += (o, e) => { tcs.TrySetResult(true); };               

                mediaElement.Play();                

                await tcs.Task;

                rootControl.Children.Remove(mediaElement);

            }

And this does seem to work on both platforms.

MVVM Cross MvxStorePage Missing for 3.2.1

Recently I upgraded from MVVMCross 3.1.1 to 3.2.1 and everything broke. The reason was that suddenly, the MvxStorePage was unavailable.

After downloading the latest MVVMCross source, I found it safe and well:

namespace Cirrious.MvvmCross.WindowsStore.Views
{
    public abstract class MvxStorePage
        : Page
          , IMvxStoreView
    {

So – the page was still there in Cirrious.MvvmCross.WindowsStore.Views, but NuGet was no longer referencing its assembly:

Cirrious.MvvmCross.WindowsStore.dll

I posted this question.

And prompted by Stuart’s comments, I revisited the MVVMCross source. The confusing thing here is that the MvxStorePage has not been moved; it’s just been ignored and replaced by the MvxWindowsPage; here’s the new version:

namespace Cirrious.MvvmCross.WindowsCommon.Views
{
    public abstract class MvxWindowsPage
        : Page
          , IMvxWindowsView
    {

I’m sure many people knew this; but I wasn’t one of them.

Binding IsSelected Method in the ListView Control in WinRT

Basically, it’s not possible. However, this is the best (and only that works) workaround that I found.

Subclass the Listview

I tried everything. Absolutely everything.

I tried straightforward binding – that doesn’t work for IsSelected.
I tried using WinRT Xaml Toolkit – didn’t work.
I tried using Setters – they don’t work for WinRT.

Finally, I came across this solution; here’s the listview subclass (stolen directly from here: http://stackoverflow.com/questions/15994021/listviewitem-isselected-binding-works-for-wpf-but-not-for-winrt):

    public class ListViewEx : ListView
    {
        protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
            
            ListViewItem listItem = element as ListViewItem;
            Binding binding = new Binding();
            binding.Mode = BindingMode.TwoWay;
            binding.Source = item;
            binding.Path = new PropertyPath("IsSelected");
            listItem.SetBinding(ListViewItem.IsSelectedProperty, binding);
        }
    }

Obviously this does restrict the IsSelected property name. My class looks something like this:

    public class Person
    {
        public string Name { get; set; }
        …
    }

I didn’t want to add an IsSelected property to this; because it doesn’t directly relate to the entity. My solution was to wrap this inside a class such as this:

    public class SelectableItem<T> : INotifyPropertyChanged
    {
        private T _item;
        public T Item 
        {
            get { return _item; }
            set
            {
                _item = value;
                RaisePropertyChanged();
            }
        }

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;                
                RaisePropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged([CallerMemberName] string name = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
}

And build it like this:

                List<Person> population = GetPeople();
                SelectablePeople = new ObservableCollection<SelectableItem<Person>>(population
                    .Select(n => new SelectableItem<Person>() { Item = n, IsSelected = false }).ToList());

So, finally, bind the collection to the new subclassed listview like this:

        <controls:ListViewEx x:Name="ItemListView" Grid.Column="0" Grid.Row="1"
                        ItemsSource="{Binding SelectablePeople}"                        
                        SelectionMode="Multiple"                        
                        Width="Auto" Height="Auto" >

            <controls:ListViewEx.ItemTemplate>
                <DataTemplate x:Name="MyTemplate">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock                            
                            Text="{Binding Item.Name}"/>
                    </StackPanel>
                </DataTemplate>
            </controls:ListViewEx.ItemTemplate>

        </controls:ListViewEx>

MVVMCross – ShowViewModel not working?

I thought I’d jot this down, as it had me for a short while. Imagine that you have a line of code that looks like this:

ShowViewModel<MyViewModel>();

But nothing happens when you call it.

The Output Window

The output window is definitely your friend with MVVMCross; it may say something like this:

mvx:Diagnostic: 36.44 Error seen during navigation request to MyViewModel – error KeyNotFoundException: Could not find view for MyApp.PCL.ViewModels.MyViewModel
at Cirrious.MvvmCross.Views.MvxViewsContainer.GetViewType(Type viewModelType)
at Cirrious.MvvmCross.WindowsStore.Views.MvxStoreViewPresenter.Show(MvxViewModelRequest request)

So, what’s the problem?

Some things to check: firstly, check that you are using an MVVMCross view; that is, for example, in Windows 8, you need your page to inherit from MvxStorePage, not Page:

Conclusion

Nothing here that you won’t see on one of Stuart Lodge’s tutorials, and probably a good handful of SO questions. So now it’s here as well.

Unit Testing Methods With Random Elements (in MVVM Cross)

Okay, quick spoiler for this: you can’t. You can’t, not really; obviously, you can write the test, but unit tests should be predictive, and a random element should not.

Solution

I imagine there are a few ways of solving this. The way shown in this post is specific to MVVM cross, but should work with any system that uses an IoC container. In brief, we’re simply going to mock out the system Random class.

How?

Well, since System.Random is the domain of Microsoft, we’ll start with a wrapper; and since this is MVVM Cross, we’ll make it a service:

    class RandomService : IRandomService
    {
        private static Random _rnd = null;

        public virtual int SelectRandomNumber(int max)
        {
            if (_rnd == null)
            {
                _rnd = new Random();
            }

            return _rnd.Next(max);
        }
    }

Couple of notes on this:
1. I haven’t posted the interface but it’s just the one method.
2. The reason for the Random class being static is that the random seed is taken from the system clock, meaning that if you call this in quick succession, there is a possibility that you would get the same number returned.
3. This is not thread safe.

Okay – all that out of the way, the code is pretty basic. Now let’s call it:

        public static T SelectRandomElement<T>(this IEnumerable<T> enumeration)
        {
            var service = Mvx.Resolve<IRandomService>();            
            int idx = service.SelectRandomNumber(enumeration.Count() + 1);

            return enumeration.ElementAt(idx);
        }

Right, so you’ll recognise the extension method from the last post, but now it retrieves the instance of the random service; here’s where we register that:

        protected override void InitViewModel()
        {
            Mvx.ConstructAndRegisterSingleton<IRandomService, RandomService>();
        }

You can actually register it anywhere you like… before it’s actually called.

Okay, so now we should have unchanged functionality; everything works as before.

The Unit Tests

The first task here is to create the mock RNG:

    class MockRandomService : IRandomService
    {
        static int _lastNumber = 0;

        public int SelectRandomNumber(int max)
        {            
            if (_lastNumber < max)
                return ++_lastNumber;
            else
            {
                _lastNumber = 0;
                return _lastNumber;
            }                
        }
    }
&#91;/sourcecode&#93;

This not allows me to determine what the next random number will be.

<strong>MVVM Cross Unit Testing</strong>

To set-up a test for MVVM Cross using the IoC container, you need to add some additional libraries to the test project first:

<a href="http://pmichaels.net/wp-content/uploads/2014/07/mvvmtest.png"><img src="http://pmichaels.net/wp-content/uploads/2014/07/mvvmtest.png?w=300" alt="mvvmtest" width="300" height="32" class="alignnone size-medium wp-image-618" /></a>


This will add Cirrious.MccmCross.Test.Core:

<a href="http://pmichaels.net/wp-content/uploads/2014/07/refs.png"><img src="http://pmichaels.net/wp-content/uploads/2014/07/refs.png" alt="refs" width="239" height="211" class="alignnone size-full wp-image-620" /></a>

And that is important, because it allows you to declare your test class as follows:


    [TestClass]
    public class ExtensionMethodTests : MvxIoCSupportingTest
    {

Inheriting from MvxIoCSupportingTest allows you to call base.Setup(), which prevents the IoC container from crashing when you call it in a test. Here’s the full unit test code:

[TestClass]
public class ExtensionMethodTests : MvxIoCSupportingTest
{
[TestMethod]
public void TestSelectRandomElement()
{
base.Setup();

Mvx.ConstructAndRegisterSingleton();

List testCollection = new List();

testCollection.Add(1);
testCollection.Add(3);
testCollection.Add(5);
testCollection.Add(7);
testCollection.Add(9);

// Cycle through all elements
for (int i = 0; i <= 5; i++) { int e = testCollection.SelectRandomElement(); Assert.AreNotEqual(e, 0); } } [TestMethod] public void TestSelectRandomElementPredicate() { base.Setup(); Mvx.ConstructAndRegisterSingleton();

List testCollection = new List();

testCollection.Add(1);
testCollection.Add(3);
testCollection.Add(5);
testCollection.Add(7);
testCollection.Add(9);

// Cycle through all elements
for (int i = 0; i <= 5; i++) { int e = testCollection.SelectRandomElement(n => n < 2); Assert.AreNotEqual(e, 1); } } } } [/sourcecode] Conclusion

So, I now have a custom RNG and unit tests that will tell me what happens when I call the method for each element. Obviously these tests are not exhaustive, but they are deterministic.