我想更好地了解TPL。例如,在任务完成之前,我将如何在屏幕上写一些东西。我无法调用“ await”,因为我希望通知主线程,而不是主动调用“ await”,并且我不想在任务完成之前停止执行。
一些示例代码:
var task = Task.Run(()=>
{
Task.Delay(10000);
});
while(true)
{
Console.WriteLine("Running...");
//I want to exit the loop the second 'task' finishes
//and print 'finished'
}
答案 0 :(得分:0)
尝试执行以下操作:
var task = Task.Run(() =>
{
Task.Delay(10000).Wait();
});
bool terminate = false;
while (!task.GetAwaiter().IsCompleted && !terminate)
{
// do something
if (task.GetAwaiter().IsCompleted) break;
// do something heavy
if (task.GetAwaiter().IsCompleted) break;
// do another heavy operation
for (int i = 0; i < 10000; i++)
{
// it took too long!
if (i == 1000)
{
terminate = true;
break;
}
}
}
答案 1 :(得分:0)
ContinueWith函数是任务上可用的方法,允许在任务完成执行后执行代码。简而言之,它允许继续。
这里要注意的是ContinueWith还返回一个Task。这意味着您可以附加ContinueWith这个方法返回的一个任务。
Task<string> t = Task.Run(() => LongRunningOperation("Continuewith", 500));
t.ContinueWith((t1) =>
{
Console.WriteLine("Running...");
});
答案 2 :(得分:0)
您可以通过以下两种方法实现此目标:
首先,您可以在Order中使用Lambda表达式来调用您的操作,但请查看代码:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
Console.WriteLine("Application thread ID: {0}",
Thread.CurrentThread.ManagedThreadId);
var t = Task.Run(() => { Console.WriteLine("Task thread ID: {0}",
Thread.CurrentThread.ManagedThreadId);
} );
t.Wait();
}
}
// The example displays the following output:
// Application thread ID: 1
//
注意t.Wait()
:
对
Wait
方法的调用可确保任务完成并 在应用程序结束之前显示其输出。不然是 可能在任务完成之前完成Main方法。
因此,我们了解必须调用Wait()
方法,以确保任务完成并显示其输出。
您还可以使用第二种方法:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
var list = new ConcurrentBag<string>();
string[] dirNames = { ".", ".." };
List<Task> tasks = new List<Task>();
foreach (var dirName in dirNames) {
Task t = Task.Run( () => { foreach(var path in Directory.GetFiles(dirName))
list.Add(path); } );
tasks.Add(t);
}
Task.WaitAll(tasks.ToArray());
foreach (Task t in tasks)
Console.WriteLine("Task {0} Status: {1}", t.Id, t.Status);
Console.WriteLine("Number of files read: {0}", list.Count);
}
}
有关更多参考,请参见Task.Run Method。
有关您的疑问的重点:
摘自Asynchronous programming with async and await (C#):
异步方法通常包含一个或多个
await
的出现 运算符,但是缺少await表达式不会导致 编译器错误。如果异步方法未使用await
运算符 标记一个悬浮点,该方法将作为同步方法执行 尽管使用了async修饰符。编译器发出警告 这样的方法。
这意味着您要么必须等待任务完成,而主线程要么必须等待这种方式。
答案 3 :(得分:0)
您可以通过创建单独的函数以在Task.Run中使用并通过引用传递参数来实现您的目标。功能应如下所示。
private void PerformTask(ref bool isComplete)
{
System.Threading.Thread.Sleep(5000);
isComplete = true;
}
从Task.Run
调用上述函数。您当前的功能应如下所示。
bool isComplete = false;
System.Threading.Tasks.Task.Run(() => PerformTask(ref isComplete));
while (!isComplete)
{
Console.WriteLine("Running...");
System.Threading.Thread.Sleep(1000);
}