0

On my web API, I want to delete a folder after my return statement.

public string Post(HttpRequestMessage request)
{
    //Do cool stuff with request
    try
    {
        return "10.0.2.2:8080/myFolder/index.html";
    }
    finally
    {
        Thread.Sleep(60000);
        Directory.Delete(myFolder, true);
    }
}

What I expected is that the device making the POST could get the return statement and load the html file. After a minute, we delete this file to free space on the server.

What happens is that the return statement is actually sent after the finally statement.

How can I run code after a return statement with delay, without delaying the return?

BeGreen
  • 765
  • 1
  • 13
  • 39
  • Things that you are trying to do is not possible, Process the operation from the calling method, after getting the response – sujith karivelil Dec 11 '17 at 10:26
  • I cannot create an async task with a `thread.sleep` inside it? Or you are telling me I need the device to make a `DELETE` call to the Web API? – BeGreen Dec 11 '17 at 10:28
  • 1
    Once you return it, the method is over. You can start a task with `Task.Delay(60000)`. – FCin Dec 11 '17 at 10:28
  • 1
    The finally-block will actually be executed before the method returns. Your current code would block for a minute, delete the folder and then return. https://dotnetfiddle.net/tReb0v – thehennyy Dec 11 '17 at 10:32
  • Ok thank you, I'll find an other way to do what I need. – BeGreen Dec 11 '17 at 10:35
  • 1
    Why not just return the file content? You are creating a tight coupling between this service that creates the file & the client that is using the file. You are creating a resource, handing a client a pointer to that resource, and then trying to guess when that client will be done with that resource so you can clean it up. That seems like a poor design choice. – Ashley Pillay Dec 11 '17 at 10:50
  • @AshleyPillay Ask my boss why he did it like this, maybe to hide some data to the end user, even if it's still possible to read it. Anyway thanks for the advice! – BeGreen Dec 11 '17 at 11:41
  • Read up on `Task.Run`. – mjwills Dec 11 '17 at 11:53

2 Answers2

3

There is no way to do that and it would be bad anyway, since you would keep resources (webserver threads for example) busy waiting.

Write another process (preferably a Windows service if you are on Windows) that checks the directory periodically and deletes all files of a certain age.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • It is the actual way it's running. But people don't read documentation, and forget about this task went they set up a new Server. – BeGreen Dec 11 '17 at 10:32
  • 2
    @BeGreen Then make it more obvious (hint) or easier to access (settings). If it exists but people don't use it because they don't know (or forget) about it, it's a usability issue. – Manfred Radlwimmer Dec 11 '17 at 10:41
  • Well, "there is no way" is not actually true in my opinion. You may queue background work on the hosting environment for example. But since this requires advanced knowledge (i.e. exception handling and so on) I am not adding this as an additional answer. No offense (really! everyone starts somehow), but I think that someone who needs advice on how `try..finally` works should perhaps stick to refactoring instead. Anyway, [this posting](https://stackoverflow.com/questions/14710822/how-to-queue-background-tasks-in-asp-net-web-api) might be a good starting point for further reading. – Peit Dec 11 '17 at 10:51
0

you can't execute code after return in my opinion you can check files if the file created before 1m delete it

DirectoryInfo objDirectoryInfo = new 
                DirectoryInfo(Server.MapPath("~/files"));
foreach (FileInfo File in objDirectoryInfo.GetFiles) {
    if ((File.LastAccessTime < DateTime.Now.AddMinutes(-1))) {
        File.Delete();
    }
}
Ibrahim Alsurkhi
  • 113
  • 1
  • 13