To cancel an asynchronious operation after a certain amount of time whilst still being able to cancel the operation manually use something like the following
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
cts.CancelAfter(5000);
This will cause a cancellation after five seconds. To cancel the operation your self all you have to do is pass the token into your async method and use the token.ThrowifCancellationRequested() method, where you have set up an event handler somewhere to fire cts.Cancel().
So a full example is:
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
cts.CancelAfter(5000);
// Set up the event handler on some button.
if (cancelSource != null)
{
    cancelHandler = delegate
    {
        Cancel(cts);
    };
    stopButton.Click -= cancelHandler;
    stopButton.Click += cancelHandler;
}
// Now launch the method.
SomeMethodAsync(token);
Where stopButton is the button you click to cancel the running task
private void Cancel(CancellationTokenSource cts)
{
    cts.Cancel();
}
and the method is defined as 
SomeMethodAsync(CancellationToken token)
{
    Task t = Task.Factory.StartNew(() => 
        {
            msTimeout = 5000;
            Pump(token);
        }, token,
           TaskCreationOptions.None,
           TaskScheduler.Default);
}
Now, to enable you to work the thread but also enable user cancellation, you will need to write a 'pumping' method 
int msTimeout;
bool timeLimitReached = false;
private void Pump(CancellationToken token)
{
    DateTime now = DateTime.Now;
    System.Timer t = new System.Timer(100);
    t.Elapsed -= t_Elapsed;
    t.Elapsed += t_Elapsed;
    t.Start();
    while(!timeLimitReached)
    {
        Thread.Sleep(250);
        token.ThrowIfCancellationRequested();
    }
}
void t_Elapsed(object sender, ElapsedEventArgs e)
{
    TimeSpan elapsed = DateTime.Now - this.readyUpInitialised;
    if (elapsed > msTimeout)
    {
        timeLimitReached = true;
        t.Stop();
        t.Dispose();
    }
}
Note, SomeAsyncMethod will return right to the caller. To block the caller aswell you will have to move the Task up in the call hierarchy.