0

I have a windows form app that run few tasks with a view to read a database sqlite send that file if it run on a machine otherwise it does the opposite (read the data and fill another sqlite database).

If i run application as user seems ok but if i create a scheduled task (on windows 10 or windows server 2012) i see the status is always running and sometimes i see in my custom logs error messages as

System.IO.Exception: process cant access file c:...mydatabase.db because is used by another process.

I think the scheduled task process not end so it try to access resources in use from previous execution It is possible?

I would to get status 'ready' as other tasks i have set.

I think making async my main method on program.cs is not good idea.

In my code you see i create sqlite database and if task is completed i create a zip file and send the zip with ftp.

static async Task Main(string[] args)
{
    args = new string[] { "ARGUMENT1" };//test
    if (args != null && args.Length > 0)
    {
        var task = args[0];
        if (task == "ARGUMENT1")
        {
            var form = new SerializerForm();
            try
            {                    
                var serialize = Task.Run(async () =>
                {
                    await form.SerializeDbToSQLiteAsync();
                });

                serialize.Wait();
                if (serialize.Status == TaskStatus.RanToCompletion)
                {
                    Task.Run(async () =>
                    {
                        await form.CompressDatabaseAsync();
                    }).Wait();

                    Task.Run(async () =>
                    {
                        await form.FtpUploadAsync();
                    }).Wait();

                    await form.SendMailAsync($"Serializer complete");
                }
            }
            catch (Exception ex)
            {
                string errorMessage = $"ex...";
                await form.SendMailAsync(errorMessage);
                await form.LogAsync("SerializationScheduled", errorMessage);
            }
        }
        else
        {
            var form = new DeserializerForm();
            //perform deserialization
    }
    else
    {
       //normal esecution windows form            
    }
}

UPDATE Although my code is bad as my english here the problem is not the use of async/await(that i repeat is bad as all of you said). I note that using static method indeed instantiate the SerializerForm object i note the code works well in both case: when user run the program and when i scheduled the app

So could you please explain why? Tks in advance

Tanveer Badar
  • 5,438
  • 2
  • 27
  • 32
herosuper
  • 164
  • 1
  • 9
  • 2
    Well at the first sight it looks you have done everything wrong when working with async/await. – Sir Rufo Oct 09 '19 at 10:13
  • Ok. please tell me all – herosuper Oct 09 '19 at 10:14
  • I have shortened your code by removing that ugly noisy Task.Run parts https://gist.github.com/SirRufo/496f0c76193c25d9bf48af0f50b1f619 – Sir Rufo Oct 09 '19 at 10:20
  • Tanks for your help. i try your code but please could you explain why is redundant the Task.Run? – herosuper Oct 09 '19 at 10:23
  • Well, you get a Task you can await. It does not make much sense to await that Task inside a Task.Run only to Wait for it - just await the first Task ... it is like painting a red wall with red paint to get it red - it will be for sure red in the end but it will waste resources – Sir Rufo Oct 09 '19 at 10:27
  • Ok i do that because i want ensure that every task start only when the previous is completed correctly – herosuper Oct 09 '19 at 10:32
  • That is exactly what `await` is doing - waiting until completion of the awaited task - there is nothing you get better/more when you do that inside a Task.Run().Wait() - except wasting resources – Sir Rufo Oct 09 '19 at 10:45
  • `Task.Run(async () =>...` is OK ([explanation](https://stackoverflow.com/questions/58277348/is-there-any-difference-between-task-runasync-await-methodasync-result/58279477#58279477)). But you must `await` it. Otherwise you have a fire-and-forget task. `await Task.Run(async () =>...` – Theodor Zoulias Oct 09 '19 at 11:51
  • But i use .Wait() ... is not what you say ? – herosuper Oct 09 '19 at 12:10
  • Why use `.Wait()` when you can use `await`? This looks like a console app, so it's not really a big deal here, but in a UI app, or web app, it's more important. Plus, it's just simpler code. The code @SirRufo showed is 15 lines less, easier to read, and achieves the same thing. – Gabriel Luci Oct 09 '19 at 12:40
  • Indeed, I missed the `Wait()`. Is there a reason that you use `Wait()` instead of `await`? – Theodor Zoulias Oct 09 '19 at 12:41
  • You might benefit from reading Microsoft's articles on asynchronous programming. They are actually quite well written. Start here: [Asynchronous programming with async and await](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/) – Gabriel Luci Oct 09 '19 at 12:42
  • I want each task start just when previous task is completed. Are dependent tasks. I dont want to upload a file when the serialization is not completed – herosuper Oct 09 '19 at 12:44
  • 1
    That's exactly the purpose of `await` :) – Gabriel Luci Oct 09 '19 at 12:57
  • Im trying your suggests... hope the task status is 'ready' at the end. Tks – herosuper Oct 09 '19 at 13:06
  • When you use `await`, it will never get to the next line unless the `Status` is `RanToCompletion` or an exception is thrown (because it's `Faulted` or `Canceled`). So there's no need to even inspect the `Status` after you use `await`. – Gabriel Luci Oct 09 '19 at 13:17
  • oK ok tks everybody...i let you know if task scheduled works fine – herosuper Oct 09 '19 at 13:25
  • You should log each task's start/completion so that you know which task makes your application to hang. Logging should by as simple and reliable as possible. Without async and serialization stuff. – Theodor Zoulias Oct 15 '19 at 16:13

0 Answers0