TPL inside Windows Service
The general design of your example is correct, however there are some problems with how you have implemented the async code. Most notibly


Calling .Wait() on the Task returned by RunAsync() will block 'OnStart()'. Instead it should be done after cancellation in the OnStop() method. This would eliminate the need to use a ManualResetEvent
Task.WaitAll() should be replace with await Task.WhenAll()


More importantly you can achieve the desired behaviour much more simply by using a System.Threading.Timer. The TPL is needed only to perform parallel processing.

public partial class FtpLink : ServiceBase
{
    private Timer _timer;

    public FtpLink()
    {
        WebEnvironment.Instance.Initialise();
    }

    protected override void OnStart(string[] args)
    {
        Trace.TraceInformation("DatabaseToFtp service started.");
        _timer = new Timer(Process, null, 0, WebEnvironment.Instance.DatabasePollInterval);
    }

    protected override void OnStop()
    {
        _timer.Dispose();
        Trace.TraceInformation("DatabaseToFtp service stopped.");
    }

    private void Process(object state)
    {
        Trace.TraceInformation("Processing message files and firmware...");

        Parallel.Invoke(
            () =&gt; new Processor().ProcessMessageFiles(),
            () =&gt; new Processor().ProcessFirmware());

        Trace.TraceInformation("Processing complete.");
    }
}


If you want to ensure that the service waits for processing to complete before exiting, you can use a simple Monitor as shown in the answer to this question.