有一个在任务中执行的过程.我不希望其中一个同时执行.
这是检查任务是否已在运行的正确方法吗?
private Task task;
public void StartTask()
{
if (task != null && (task.Status == TaskStatus.Running || task.Status == TaskStatus.WaitingToRun || task.Status == TaskStatus.WaitingForActivation))
{
Logger.Log("Task has attempted to start while already running");
}
else
{
Logger.Log("Task has began");
task = Task.Factory.StartNew(() =>
{
// Stuff
});
}
}
Run Code Online (Sandbox Code Playgroud) Sometimes, once I have requested the cancellation of a pending task with CancellationTokenSource.Cancel, I need to make sure the task has properly reached the cancelled state, before I can continue. Most often I face this situation when the app is terminating and I want to cancel all pending task gracefully. However, it can also be a requirement of the UI workflow specification, when the new background process can only start if the current pending one has been fully …
如果我需要推迟代码执行,直到UI线程消息循环的未来迭代之后,我可以这样做:
await Task.Factory.StartNew(
() => {
MessageBox.Show("Hello!");
},
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)
这将类似于await Task.Yield(); MessageBox.Show("Hello!");,除了我有一个选项可以取消任务,如果我想.
在使用默认同步上下文的情况下,我可以类似地使用await Task.Run继续池线程.
事实上,我喜欢Task.Factory.StartNew和Task.Run更多Task.Yield,因为他们都明确定义了延续代码的范围.
那么,在什么情况下await Task.Yield()实际上有用呢?
我有以下场景,我认为这可能很常见:
有一个任务(一个UI命令处理程序)可以同步或异步完成.
命令的到达速度可能比处理它们的速度快.
如果命令已有待处理任务,则应对新命令处理程序任务进行排队并按顺序处理.
每个新任务的结果可能取决于前一个任务的结果.
应该遵守取消,但为了简单起见,我想将其排除在本问题的范围之外.此外,线程安全(并发)不是必需的,但必须支持重入.
这是我想要实现的基本示例(作为控制台应用程序,为简单起见):
using System;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var asyncOp = new AsyncOp<int>();
Func<int, Task<int>> handleAsync = async (arg) =>
{
Console.WriteLine("this task arg: " + arg);
//await Task.Delay(arg); // make it async
return await Task.FromResult(arg); // sync
};
Console.WriteLine("Test #1...");
asyncOp.RunAsync(() => handleAsync(1000));
asyncOp.RunAsync(() => handleAsync(900));
asyncOp.RunAsync(() => handleAsync(800));
asyncOp.CurrentTask.Wait();
Console.WriteLine("\nPress any key to continue to test #2...");
Console.ReadLine();
asyncOp.RunAsync(() =>
{
asyncOp.RunAsync(() => handleAsync(200)); …Run Code Online (Sandbox Code Playgroud) 我有一个需要定期运行的任务.我的第一个实现是:
public static void CheckTask(CancellationTokenSource tokenSource)
{
do
{
// Do some processing
Console.WriteLine("Processing");
// Sleep awhile and wait for cancellation
// If not cancelled, repeat
} while (!tokenSource.Token.WaitHandle.WaitOne(1500));
Console.WriteLine("Bye bye");
}
Run Code Online (Sandbox Code Playgroud)
此任务是这样开始的:
CancellationTokenSource tokenSource = new CancellationTokenSource();
Task task = null;
task = new Task((x)=> {
CheckTask(tokenSource);
//CheckTask2(t, (object)tokenSource);
}, tokenSource.Token);
task.Start();
Run Code Online (Sandbox Code Playgroud)
然后我想而不是在任务中循环,为什么不使用ContinueWith重新安排它呢?我的下一个实现是这样的:
public static void CheckTask2(Task task, object objParam)
{
CancellationTokenSource tokenSource = (CancellationTokenSource)objParam;
// Do some processing
Console.WriteLine("Processing");
// Sleep awhile and wait for cancellation
if(tokenSource.Token.WaitHandle.WaitOne(1500))
{ …Run Code Online (Sandbox Code Playgroud)