Its kind of unclear what you are asking or what you are exactly trying to achieve, however here is an example using Task
running 2 endless loops (until a cancellation token is called)
public static void Method1(CancellationToken token)
{
Task.Run(
async () =>
{
while (!token.IsCancellationRequested)
{
// do something
await Task.Delay(500, token); // <- await with cancellation
Console.WriteLine("Method1");
}
}, token);
}
public static void Method2(CancellationToken token)
{
Task.Run(
async () =>
{
while (!token.IsCancellationRequested)
{
// do something
await Task.Delay(300, token); // <- await with cancellation
Console.WriteLine("Method2");
}
}, token);
}
private static void Main(string[] args)
{
var source = new CancellationTokenSource();
Method1(source.Token);
Method2(source.Token);
source.CancelAfter(3000);
Console.ReadKey();
}
Demo Here
Task vs Thread differences
Thread
is a lower-level concept: if you're directly starting a
thread, you know it will be a separate thread, rather than executing
on the thread pool etc.
Task
is more than just an abstraction of "where to run some code"
though - it's really just "the promise of a result in the future". So
as some different examples:
Task.Delay
doesn't need any actual CPU time; it's just like setting a timer to go off in the future
- A task returned by
WebClient.DownloadStringTaskAsync
won't take much CPU time locally; it's representing a result which is likely to
spend most of its time in network latency or remote work (at the web
server)
- A task returned by
Task.Run()
really is saying "I want you to execute this code separately"; the exact thread on which that code
executes depends on a number of factors.
Note that the Task<T>
abstraction is pivotal to the async support in
C# 5.
In general, I'd recommend that you use the higher level abstraction
wherever you can: in modern C# code you should rarely need to
explicitly start your own thread.
Quote Jon Skeet