0

I have an abstract class FilesManager which manages some files.

The methods are marked as Task<> because i might be saving / reading the files to a cloud server via http request, so i want to mark them as asynchronous.

However, for now, i save the files on local disk, synchronusly.

Is ok to return empty Task in order to fix the error?

For example:

return Task.Factory.StartNew(() => { return; });

The below implementation of LocalDiskFilesManager throws exception, because each method is expected to return a Task<> object.

public abstract class FilesManager
{
    public abstract Task SaveFileAsync(XDocument xDocument);
    public abstract Task<XDocument> GetFileAsync(Guid file_Id);
}

// Synchronously
public class LocalDiskFilesManager : FilesManager
{
    public override Task SaveFileAsync(XDocument xDocument)
    {
        string path = GetFilePath();
        xDocument.Save(path);

        // is ok to return an empty task? does it affects the performance / threads?
        // return Task.Factory.StartNew(() => { return; });
    }

    public override Task<XDocument> GetFileAsync(Guid file_Id)
    {
        string path = GetFilePath(file_Id);
        XDocument xDocument = XDocument.Load(path);

        return xDocument;

        // is ok to return an empty task? does it affects the performance / threads?
        // return Task<XDocument>.Factory.StartNew(() => { return xDocument; });
    }
}
Catalin
  • 11,503
  • 19
  • 74
  • 147
  • Also see [this answer](http://stackoverflow.com/a/11782373/706456) – oleksii Jan 30 '15 at 11:11
  • I think that answer explains how to run an asynchronous task synchronously, but i need to know how to "fake" a synchronous task to look asynchronous :) – Catalin Jan 30 '15 at 11:15

1 Answers1

3

Better would be to use Task.FromResult for now.

Creates a Task<TResult> that's completed successfully with the specified result.

E.g.

public override Task<XDocument> GetFileAsync(Guid file_Id)
{
    string path = GetFilePath(file_Id);
    XDocument xDocument = XDocument.Load(path);

    return Task.FromResult(xDocument);
}

Which avoids actually scheduling a separate task so should address your threading concerns.

And for the non-generic Task, I'd usually just do:

private static Task _alreadyDone = Task.FromResult(false);

public override Task SaveFileAsync(XDocument xDocument)
{
    string path = GetFilePath();
    xDocument.Save(path);

    return _alreadyDone;
}
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • Great! Thank you. is there any specific reason you marked the `_alreadyDone` as static? – Catalin Jan 30 '15 at 11:10
  • @RaraituL - It's a premature optimization - you could just have the method `return Task.FromResult(false);` but since there's nothing interesting in that task we may as well create one, once, and always return it. Saving an allocation. – Damien_The_Unbeliever Jan 30 '15 at 11:15