Tasks seem to start automatically
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?
精彩评论