开发者

Tasks seem to start automatically

开发者 https://www.devze.com 2023-01-30 13:00 出处:网络
I\'m porting a program that had a very long loading time which was not improved at all when I ported it, as the slowness was because of accessing a db-server (and not sub-optimal code).I have moved th

I'm porting a program that had a very long loading time which was not improved at all when I ported it, as the slowness was because of accessing a db-server (and not sub-optimal code). I have moved the loading onto a separate thread with the Tasks library and now the UI doesn't freeze as it loads, but it did make me curious about something:

The Task.Factory object has a method StartNew which is supposed to create a new task, start it, and return a reference to it. This makes sense, but it seems that the Task constructor does the exact same thing.

When I do the following:

Task catsFromDB = new Task(() => AddCategoriesFromDB(cts.Token), cts.Token);
catsFromDB.Start();

I get an error InvalidOperationException which I really don't understand. It seems to believe that I've kicked it off already. Which I haven't.

[EDIT]

The erorr is: "InvalidOperationException, Start may not be called on task that has completed"

[EDIT]

The error was some cancellation code I included开发者_运维问答. I needed to reset the cancellation before trying to run it again.


Now I feel stupid, but it will be instructive to let others learn from my 'green' (as in "new", "inexperienced") error:

I needed the operation in question to be cancellable and re-runnable, so I had implemented a "CancelLoad" operation which always got run before doing the actual load. It turns out that I forgot to create a new Token after canceling and waiting.


I'm unable to reproduce that behaviour. The code below only starts the task when you call Start.

using System;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        var cts = new CancellationTokenSource();
        Console.WriteLine("Creating task...");
        Task task = new Task(() => Console.WriteLine("Task executing"),
                             cts.Token);
        Console.WriteLine("Sleeping...");
        Thread.Sleep(1000);
        Console.WriteLine("Starting task...");
        task.Start();
        Thread.Sleep(1000);
    }
}

My guess is that somehow you're creating multiple tasks and starting some of them twice, and some of them not at all. If you can show a similar short-but-complete program which demonstrates the problem, we should be able to help more.


My guess is more UI related: I think you might have code within AddCategoriesFromDB(cts.Token) that tries to update the UI. However, since you're now on a different thread than the UI is, your updates to the UI will throw errors. Is this the case?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号