Sunday, 18 January 2015

Xamarin Forms–Using background images on iOS

Following on from my last post on creating A Light status bar for iOS, I wanted to go one step further and add in a full-screen background image to my application. This is very easy without a navigation bar, but with one it’s a bit more involved so I thought a blog post would be in order.

If you have no navigation bar then all you really need to do is create an image of the right size (for each physical phone you want to support, such as 4S, 5S, 6, 6 Plus), add images to the resources directory and use them in code or XAML. With a navigation bar it’s a bit more involved as you need to split your source image into two separate images (one for the navigation bar and one for the remainder of the screen).

Then when you have the images defined you need to hook the images to the correct controls, and this is where it gets a little more complex. With a NavigationPage we need to set the navigation bar’s background to an image – but we can’t do this in regular Xamarin Forms code as the property is only available in a custom renderer, so we’ll need to create one.

First off though we need an image – I chose one I took in 2006 whilst on holiday with my family – this is the last time we were all together and it was a beautiful day. Anyhow, I extracted four images in total as shown in the following…

Original Marked Up

The red outline contains the navigation bar image (640px * 128px) and the background image (640px * 1008px) – these are both for an iPhone 5S which is what I have to develop on at the moment.

The green outline contains the two images for the landscape view, the navigation bar being 1136px * 64px, and the background image being 1136px * 576px. The navigation bar is shorter by default in landscape mode as the status bar is switched off. I believe it’s possible to override this and display the status bar, but I don’t need that so haven’t looked into it further.

I named those images as follows…

  • PortraitNavBar@2x.png
  • PortraitBackgrouns@2x.png
  • LandscapeNavBar@2x.png
  • LandscapeBackground@2x.png

With that done I then needed to write a bit of code. First up I had to ensure that the correct background image was shown for the content page – this was simply a job of overriding the OnSizeAllocated member of my content page…

    protected override void OnSizeAllocated (double width, double height)
{
base.OnSizeAllocated (width, height);

if (width < height)
this.BackgroundImage = "PortraitBackground.png";
else
this.BackgroundImage = "LandscapeBackground.png";

}

The OnSizeAllocated method is called when the size changes on the phone and it provides the size of the page, so this seemed like a reasonable place to determine which image to load up.


Then I needed to add in a custom render so added a deriver navigation page as shown below…

    public class CustomNavigationPage : NavigationPage
{
public CustomNavigationPage (Page content) : base(content)
{
}
}

With that defined I could then add the renderer. The purpose of this renderer is to render the background image of the navigation bar...

[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(XamFormsTestbed.iOS.Renderers.CustomNavigationPageRenderer))]

namespace XamFormsTestbed.iOS.Renderers
{
public class CustomNavigationPageRenderer : NavigationRenderer
{
public override void ViewDidLoad ()
{
base.ViewDidLoad ();

var img = UIImage.FromBundle ("PortraitNavBar.png");
this.NavigationBar.SetBackgroundImage (img, UIBarMetrics.Default);

img = UIImage.FromBundle ("LandscapeNavBar.png");
this.NavigationBar.SetBackgroundImage (img, UIBarMetrics.Compact);
}
}
}

Originally I'd tried responding to size changes here, but then read an article that discussed the above mechanism and it appeared to work.


With all that in place I can now display a background image in the navigation bar and also have a correctly formatted image for both landscape and portrait orientations...

IMG_1302

IMG_1303


And there you have it – a full background image with a navigation bar. Hopefully this will help someone with their application.

Saturday, 17 January 2015

Xamarin Forms – A light status bar for iOS

I’m writing an app in Xamarin Forms at the moment and as part of that I want to have a light on dark theme rather than the dark on light default. Ultimately there will be a background image on the pages that extends into the navigation area at the top of the screen, but for now a coloured backgound will do. This post will show how to accomplish this.

I started with a simple Xamarin Forms app and set the BackgroundColor of the content page to Green, here’s what I got…

Screen Shot 2015-01-17 at 10.26.28

That status bar isn’t much good is it? To alter it you need to do two things…

  • Alter the info.plist file and set the Status Bar Style to LightContent
  • Add an additional item to the .plist file

Open info.plist and scroll down to the following section…

Screen Shot 2015-01-17 at 10.27.07

You may or may not want a status bar whilst the app is starting up – if not then check “Hide during application launch”.

Next, at the bottom of the plist editor there’s three tabs, click on Source and then add in the following…

Screen Shot 2015-01-17 at 10.27.42When you click “Add New Entry” you can then select “View controller-based status bar appearance” from the dropdown, then click/tab off it and it’ll change the type column to Boolean. The default is Yes, you need to set it to No.

With that done, rebuild your app and run it and voila, you get this…

Screen Shot 2015-01-17 at 10.28.18

Looking good! But that’s not the end of the story – what happens when you add a navigation bar to the app? Ah, well – you get this…

Screen Shot 2015-01-17 at 10.29.52

That’s with the following code in my App.cs file…

public class App
{
    public static Page GetMainPage ()
    {   
        var mainPage = new MainPage ();
        var navPage = new NavigationPage (mainPage);
        navPage.BarBackgroundColor = Color.Green;
        return navPage;
    }
}

And if I happen to set a title on my content page it shows as follows…

Screen Shot 2015-01-17 at 10.57.05

Now at this point in my travels around the intertubes I found a bunch of articles that stated I should override some method of the view and explicitly state that I wanted a light status bar. I spent a load of time on this but all to no avail, so I went back to the original code and had a poke around and what did I find but the BarTextColor property. Setting that had the desired effect…

Screen Shot 2015-01-17 at 10.57.44

The code is now as follows…

public class App
{
    public static Page GetMainPage ()
    {   
        var mainPage = new MainPage ();
        var navPage = new NavigationPage (mainPage);
        navPage.BarBackgroundColor = Color.Green;
        navPage.BarTextColor = Color.White;
        return navPage;
    }
}

I hope that helps someone as there seems to be a lot of misinformation on the intertubes about how to get this to work. I’m on the latest Xamarin Forms build, as of today that’s 1.3.1.6296.

Thursday, 18 December 2014

Getting NServiceBus, SignalR and Autofac to work together

I’m currently working on an existing web app that we’re updating to add in NServiceBus and SignalR. A broad brush overview is shown below…

image

Here a request is sent from the browser which goes to a SignalR hub inside the website. That request is then sent onto the bus and some back end magic happens, which ultimately ends up in a response being sent to the bus. This is picked up by the website and a response is pushed down to the client courtesy of SignalR.

If we look into what’s happening inside the website we see the following…

image

The hub implements an interface that’s injected into the message handler, so that the handler can call back to the hub when the response message comes in, which ultimately then makes the hub call back to the browser to finish the loop.

Getting all this setup was a bit of a bother and I went down a few blind alleys before getting it all to work properly, hence documenting it so that I can hopefully short-circuit someone else’s work.

In pseudocode this is what happens…

  • The browser makes a request to the hub.
  • The hub code creates a unique Request Id, and stuffs this into a dictionary, mapping this Request Id to the SignalR Context.ConnectionId.
  • The hub then sends a message onto the bus, this contains the Request Id.
  • After the back-end has processed this message a response is placed on the bus, again containing the Request Id.
  • The message handler receives the message and uses the callback interface and Request Id to build a dynamic object that we can call the browser back with.
  • The message handler then makes the callback.

For this example I’m doing the callback within the message handler, but you could encapsulate this fully within the Hub too if you prefer. OK, enough explanation, on to some code…

    public interface ICallback
{
dynamic GetCallback(Guid requestId);
}



This interface is used to communicate between the message handler and the Hub. In addition I added a “registration” service that is used to map a Request Id to a client connection Id…

    public interface IRegistration
{
void Register(Guid id, string data);

string GetRegistration(Guid id);
}



The implementation of this service was a simple dictionary, this however should be beefed up as it needs a “tidy up” mechanism that will ensure that data is removed from this dictionary when the client disappears. The hub then is as shown below…

    public class WibbleHub : Hub, ICallback
{
public WibbleHub(IBus bus, IRegistration registration)
{
_bus = bus;
_reg = registration;
}

public void RequestWibble(string text)
{
Guid requestId = Guid.NewGuid();

_reg.Register(requestId, Context.ConnectionId);

_bus.Send(new WibbleMessage { RequestId = requestId, Text = text});
}

public dynamic GetCallback(Guid requestId)
{
dynamic callback = null;
string clientId = _reg.GetRegistration(requestId);

if (null != clientId)
callback = Clients.Client(clientId);

return callback;
}

private IBus _bus;
private IRegistration _reg;
}



The hub imports the bus and registration services, and the RequestWibble method is the one we’re calling from the web client. This registers the mapping between the Request Id and the client Connection Id, and then sends a message onto the bus.


The GetCallback method uses the registration service to find the client connection Id, then returns a dynamic object hooked to that client if the Id matches one that has been registered.


The message handler is fairly simple too…

    public class WibbleHandler : IHandleMessages<WibbleMessage>
{
public WibbleHandler(ICallback callback)
{
_callback = callback;
}

public void Handle(WibbleMessage message)
{
var cb = _callback.GetCallback(message.RequestId);

if (null != cb)
{
try
{
cb.wibbleSucceeded(message.Text);
}
catch (Exception ex)
{
int i = 0;
}
}
}

private ICallback _callback;
}



The handler imports the ICallback interface (exposed by the Hub), and when it handles the incoming message it calls the GetCallback() method to retrieve the dynamic object that allows us to call down to the web client.


The last piece of the puzzle is wiring this up, and that was the main thing that took time to get right, mainly down to my misunderstanding of how NServiceBus does its stuff. I created a DependenciesConfig file as follows…

    public static class DependencyConfig
{
public static void BuildDependencies()
{
var container = BuildContainer();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

public static IContainer BuildContainer()
{
if (null == _container)
{
var builder = new ContainerBuilder();

builder.RegisterControllers(Assembly.GetExecutingAssembly())
.PropertiesAutowired();

builder.RegisterType<WibbleHub>()
.AsSelf()
.As<ICallback>()
.ExternallyOwned()
.SingleInstance();

builder.RegisterType<Registration>().As<IRegistration>().SingleInstance();

_container = builder.Build();

var config = new BusConfiguration();
config.UsePersistence<InMemoryPersistence>();
config.UseTransport<RabbitMQTransport>();
config.UseContainer<AutofacBuilder>(c => c.ExistingLifetimeScope(_container));

var bus = Bus.Create(config);
bus.Start();

}

return _container;
}

private static IContainer _container;
}



This has a static BuildContainer method that creates the AutoFac container, and there are a couple of things of note. First off is the registration of the hub, this is registered as a singleton, as is the registration service too.


Then (and this is the bit that I got wrong) is the configuration of the bus. First off, the container is built before the bus is constructed, so the bus itself is not constructed as part of the container itself, it lives “outside”. The bus is setup to hook to the Autofac container using the UseContainer() member, this links the bus to the registered components, and means that when a message comes in on the bus that it can resolve all dependencies such as the ICallback interface exposed by the hub.


Now to the voodoo magic. In the above there is nowhere that the bus itself is registered with the Autofac container, so conventional wisdom would dictate that any components requiring IBus wouldn’t be able to resolve it, so for example this controller shouldn’t work…

    public class DefaultController : Controller
{
public DefaultController(IBus bus)
{
_bus = bus;
}

public ActionResult Index()
{
return View();
}

private IBus _bus;
}



But it does work. How is a mystery. After a bit of searching I came across this post on Stack Overflow that indicates that NSB does this for you. That’s great, but also somewhat confusing for anyone who doesn’t know this beforehand, which presumably is everyone who uses NSB and Autofac, or any IOC container probably as people are used to registering dependencies themselves, rather than some magic happening. Personally I’m not a fan of this magic, it’ll most likely trip you up. However, with this in place it all works as expected – I can then pop some Javascript into my client and everything works as expected.


There’s one more class to add and that’s the startup for Owin, so that we can get SignalR up and running properly…

    public class Startup
{
public void Configuration(IAppBuilder app)
{
var container = DependencyConfig.BuildContainer();

GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);
app.UseAutofacMiddleware(container);
app.MapSignalR(new HubConfiguration { EnableDetailedErrors = true });
}
}



The demo (attached) has a simple form where you can enter text, click a button and lo and behold a message is displayed on screen. That’s pretty useless, but at least is shows how NServiceBus, Autofac and SIgnalR can play nicely together. I’m using RabbitMQ as my messaging infrastructure, feel free to bring your own along if you would prefer.


Hope this helps someone!

Monday, 17 November 2014

Fun (or rather not) with EventSource

I’ve been an advocate of good logging in applications (especially server side ones) for many years, and today I’m working on something for myself and wanted to use the latest and greatest event logging framework so chose System.Diagnostics.Tracing (which has been around since .NET 4 days). I’ve used it before but today I came across an issue that had me stumped for some time.

I’d created a custom event source, and derived this from an interface so that I could inject an implementation in at runtime…

  public interface ILogger
{
void T1(string message);
void T2(string message);
}

public class Logger : EventSource, ILogger
{
public void T1(string message) { this.WriteEvent(1, message); }
public void T2(string message) { this.WriteEvent(2, message); }
}

But when I used PerfView to view my events there were none. After a lot of head scratching I tried a sample from Vance’s blog (which seems to be the main place to get any information about this feature) and of course that worked first time. I did some more fiddling in code and then stumbled across the reason as I was debugging the code. It’s worthy of a blog post, as this may well catch someone else out.


I’d created the interface and implemented it in the EventSource derived class so that I could mock out the logger code for testing – however this was the part that caught me out. When the code runs, the EventSource class builds a manifest that contains details of the "events" that are written out – and this uses the following bit of reflection to get all the methods that we want to expose as "events" in the ETW trace…

  MethodInfo[] methods = eventSourceType.GetMethods(BindingFlags.NonPublic | 
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly);

I’ve highlighted the offending enum value above. This is saying "find me all methods whether public or not, defined on this Instance ONLY". So, because I’d created an interface and then implemented that interface, my methods were not found by the code that generates the manifest, and hence I wasn’t getting anything useful in the ETL file.


The net effect of this is that I cannot directly use an interface to define an interface for the events I want to emit. There are a few ways around this I can think up…



  • Hard-code the logger class as in the examples on Vance’s posts. Nope, not going to fly, I this stuff to be mockable/testable!
  • Create an EventSource derived class and add shim methods to call the actual logging methods
  • Write my own version of EventSource, seems like a lot of work for little gain!
  • Create a shim class that forwards all calls to the EventSource derived class

Of these I picked the last, as I do want my event source code to be mockable, and it seemed to be the least bad of the options, so I ended up with the following class...

  public class ActualLogger : EventSource
{
public void T1(string message) { this.WriteEvent(1, message); }
public void T2(string message) { this.WriteEvent(2, message); }
public static ActualLogger Instance { get { return _instance; } }
static ActualLogger _instance = new ActualLogger();
}

public class Logger : ILogger
{
public void T1(string message) { ActualLogger.Instance.T1(message); }
public void T2(string message) { ActualLogger.Instance.T2(message); }
}

Well, something like that anyway!


As an aside, if you want to look at the manifest that is generated from your EventSource derived class, there's a static method on EventSource that can be useful...

    var manifest = EventSource.GenerateManifest(typeof(ActualLogger), typeof(ActualLogger).Assembly.Location);

Hope this helps someone!

Thursday, 23 October 2014

ComboBox binding in Workflow activities

Today I was creating a simple activity with a couple of combo boxes, and came across a problem where the binding wasn’t working correctly (well, at all). I had an InArgument<string> property on my activity, and wanted to set this from a combo box on the design surface. I guess I haven’t done this before as it doesn’t work out of the box, and you need to write an IValueConverter to get it working. I’ve trodden this path before but this was a bit of a tricky beast.

After some wailing and gnashing I came up with the following base class converter…

public abstract class ComboBoxToModelItemConverter<T> : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
T retVal = default(T);

ModelItem mi = value as ModelItem;

if (null != mi)
{
var arg = mi.GetCurrentValue() as InArgument<T>;

if (null != arg)
{
var expression = arg.Expression;
var literal = expression as Literal<T>;

if (null != literal)
retVal = literal.Value;
}
}

return retVal;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return new InArgument<T>((T)value);
}
}





I then created a concrete class to bind to InArgument<string>…

public class ComboBoxStringToModelItemConverter : ComboBoxToModelItemConverter<string>
{
}



With that created I could then get the binding to work by adding the converter to the binding. I have a class that contains TemplateId and Name, I wish to show the Name on screen but store the TemplateId (and this is mapped to an InArgument<string> on the activity). The XAML is as follows…

<local:ComboBoxStringToModelItemConverter x:Key="comboConverter"/>


<ComboBox ItemsSource="{Binding Templates}" 
SelectedValue="{Binding ModelItem.TemplateId, Converter={StaticResource comboConverter}}"
SelectedValuePath
="TemplateId" DisplayMemberPath="Name" />



With that done it all works as expected. I’m surprised that a converter such as this doesn’t exist in the Workflow libraries – and also in the many, many years I’ve been playing with Workflow that I’ve not needed one. Anyhow, I hope this is of use to someone!

Tuesday, 30 September 2014

Fun with ExpressionTextBox

After a short hiatus doing other things (a lot of back-end services work) I’m back in the fray with Workflow.

Yesterday, a colleague asked me to help out with an activity he was building that works like a combination of an If and a ForEach. The basic premise is that we have a List<Something>, and want to iterate through that list until we find a match with a Predicate<Something>, in which case we then schedule a child activity.

So, I came up with the following…

image

Here we have a collection of Noodle’s (as an argument called Stuff), and we’re going to iterate through all elements in the collection until we find the first that matches the predicate (x => x.Name == “Sausages”). When found, we then execute the Body activity, with item as the variable holding the selected Noodle instance.

The activity code is fairly simple…

    public class Find<T> : NativeActivity, IActivityTemplateFactory
{
public InArgument<IEnumerable<T>> Values { get; set; }

public ActivityAction<T> Body { get; set; }

public InArgument<Predicate<T>> Match { get; set; }

protected override void Execute(NativeActivityContext context)
{
var match = this.Match.Get(context);

// Iterate through the collection and if we find a match, we're sorted...
foreach(var o in Values.Get(context))
{
if (match(o))
{
context.ScheduleAction<T>(this.Body, o);
break;
}
}
}

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
...
}

public Activity Create(DependencyObject target)
{
...
}
}



The activity contains a collection of type T, a body that is passed the selected value from the collection, and a predicate that matches against the items in the collection. I’ve also overridden CacheMetadata to setup all of the arguments correctly, and in addition implemented IActivityTemplateFactory as there’s some setup that needs to be done when the activity is created in order to get it to work correctly. Full details are in the code download.


In the Execute method I iterate through the elements in the collection and execute the Match function against each. For the first that matches I then schedule the body activity, passing through the selected element. This then terminates the loop (that’s what we wanted, a more standard implementation might iterate though all matching elements in the collection.


The Designer


The important thing about the code is the designer (and that’s why I wrote the post in the first place). It’s fairly rudimentary, but there is something that might trip you up which is why I wrote this post.


The designer XAML contains a couple of ExpressionTextBox’s as shown in the image below…


image


The first is bound to the Values property on the activity, the second to the Match property. The important thing to note is that in order to get these to work properly you *must* use the ExpressionType property of the ExpressionTextBox…

    <sapv:ExpressionTextBox
Expression="{Binding ModelItem.Values, Mode=TwoWay,
Converter={StaticResource argToExpressionConverter}}"

OwnerActivity="{Binding ModelItem, Mode=OneWay}"
ExpressionType="{Binding ListType}"/>



Now, the type of items in the bound List is based on the type of element you choose to fill the list – in my case I have Noodles. So, the ExpressionType for the list would be IEnumerable<Noodle>, and the datatype for the predicate would be Predicate<Noodle>.


If you don’t use the ExpressionType property of the ExpressionTextBox then the text box will essentially be one-way, it will bind to values you set on the property grid, but won’t allow you to push values the other way (even if those values match 1:1 with what you type in the property grid). So, ExpressionType is mandatory, and has to be the right type.


In order to get the right type, I have created two properties on the Designer, and these call down to the underlying activity to get the actual type necessary. As an example here’s the code for the ListType…

    public Type ListType
{
get
{
if (null == _listType)
{
var findActivity = this.ModelItem.GetCurrentValue();

var valuesProp = findActivity.GetType().GetProperty("Values");

var args = valuesProp.PropertyType.GenericTypeArguments;

_listType = args[0];
}

return _listType;
}
}

private Type _listType;



This code gets the fund activity which is exposed through the ModelItem (which is a proxy object over the activity you are editing). I then lookup the Values property and return the first generic argument – in my example this will be IEnumerable<Noodle>. I have a similar property for the match predicate.


The Code


If you want to have look at the full code please click to download it…

Tuesday, 8 July 2014

Polling with Timeout in .NET 4.5

A couple of times recently I have needed to be able to wait (asynchronously) for something to happen, but also permit a timeout to occur. I wrote a version of this many moons ago that used wait handles and was pretty difficult to understand, now with async support in .NET I decided to rewrite it.

The basic premise is that I want to be able to call the following…

while (not done and not timedout)
{
if (signalFunc())
return (dataFunc());
else
wait a bit;
}


The signalFunc() is called to check that something has happened. The dataFunc() returns the actual data you are waiting for.

One of the places I need this is when trying to make a fully asynchronous pipeline in Azure look like a synchronous function to the caller. A request comes in, gets queued, gets processed, gets queued again, and gets processed again before being complete – and I want a way to hide all of this complexity from a caller so that we can provide an API that looks synchronous to the caller, but is actually asynchronous internally.


In this case I add a sentinel value to the database that the signalFunc() looks for, and then push the request into my Azure pipeline. The signalFunc() is polled repeatedly and, once the request has passed al the way through my request pipeline it updates the sentinel in the database. The signalFunc() will then report true and I can then execute the dataFunc() to find whatever it is the caller needs and return it to them.


So, after having rewritten this using async I have arrived at the following API…

public static Task<T> PollWithTimeoutAsync<T>(Func<bool> signalFunc, Func<T> dataFunc, int millisecondsBetweenPolls, int millisecondsToTimeout)



There’s also another one that includes a cancellation token. The signalFunc() is called repeatedly (with a delay of millisecondsBetweenPolls) and if true the dataFunc() is called to provide the data. The whole operation waits at most millisecondsToTimeout before throwing a TimeoutException.


The full code is as follows…

public static async Task<T> PollWithTimeoutAsync<T>(Func<bool> signalFunc, Func<T> dataFunc, int millisecondsBetweenPolls, int millisecondsToTimeout)
{
if (null == signalFunc) throw new ArgumentNullException("signalFunc");
if (null == dataFunc) throw new ArgumentNullException("dataFunc");
if (millisecondsBetweenPolls >= millisecondsToTimeout) throw new ArgumentException("The millisecondsBetweenPolls should be less than millisecondsToTimeout");

using (var cts = new CancellationTokenSource(millisecondsToTimeout))
{
bool done = signalFunc();

while (!done)
{
try
{
await Task.Delay(millisecondsBetweenPolls, cts.Token);
}
catch (TaskCanceledException)
{
throw new TimeoutException();
}

done = signalFunc();
}

return dataFunc();
}
}



It’s fairly terse (isn’t all good code like that?) and uses a feature of CancellationTokenSource which helps out a lot here, as the override I have used ensures that the token is cancelled after the period defined by the millisecondsToTimeout parameter. So, I setup a cancellation token source to go off in a few seconds, then loop calling the signalFunc() and if that reports false, use Task.Delay() to wait for a while before polling again. The beauty of Task.Delay is that it’s also cancellable by using a cancellation token, so if I’m in the middle of waiting and the overall timeout expires, the delay task will throw a TaskCancelledException, which I convert into a TimeoutException before throwing it up the chain.


Here I’m basically waiting in a loop, periodically calling the signalFunc(), but able to fail when the cancellation token timer fires. Simple and elegant!


If you want the version that also has a cancellation token then that’s here for you too…

public static async Task<T> PollWithTimeoutAsync<T>(Func<bool> signalFunc, Func<T> dataFunc, int millisecondsBetweenPolls, int millisecondsToTimeout, CancellationToken cancellationToken)
{
if (null == signalFunc) throw new ArgumentNullException("signalFunc");
if (null == dataFunc) throw new ArgumentNullException("dataFunc");
if (millisecondsBetweenPolls >= millisecondsToTimeout) throw new ArgumentException("The millisecondsBetweenPolls should be less than millisecondsToTimeout");

using (var cts = new CancellationTokenSource(millisecondsToTimeout))
{
using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken))
{
bool done = signalFunc();

while (!done)
{
try
{
await Task.Delay(millisecondsBetweenPolls, linkedCts.Token);
}
catch (TaskCanceledException)
{
// Was this a timeout?
if (cts.IsCancellationRequested)
throw new TimeoutException();
else
// No, it was most probably the outer cancellation token
throw;
}
done = signalFunc();
}

return dataFunc();
}
}
}



Hopefully someone will find this useful. If you want the code, complete with unit tests then please click here.