相关疑难解决方法(0)

在开始新任务之前检查任务是否已在运行

有一个在任务中执行的过程.我不希望其中一个同时执行.

这是检查任务是否已在运行的正确方法吗?

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)

.net c# parallel-processing task-parallel-library

33
推荐指数
2
解决办法
3万
查看次数

Cancelling a pending task synchronously on the UI thread

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 …

.net c# multithreading task-parallel-library async-await

22
推荐指数
3
解决办法
5104
查看次数

"等待Task.Yield()"及其替代品

如果我需要推迟代码执行,直到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.StartNewTask.Run更多Task.Yield,因为他们都明确定义了延续代码的范围.

那么,在什么情况下await Task.Yield()实际上有用呢?

.net c# task-parallel-library async-await

21
推荐指数
3
解决办法
1万
查看次数

任务排序和重新进入

我有以下场景,我认为这可能很常见:

  1. 有一个任务(一个UI命令处理程序)可以同步或异步完成.

  2. 命令的到达速度可能比处理它们的速度快.

  3. 如果命令已有待处理任务,则应对新命令处理程序任务进行排队并按顺序处理.

  4. 每个新任务的结果可能取决于前一个任务的结果.

应该遵守取消,但为了简单起见,我想将其排除在本问题的范围之外.此外,线程安全(并发)不是必需的,但必须支持重入.

这是我想要实现的基本示例(作为控制台应用程序,为简单起见):

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)

.net c# asynchronous task-parallel-library async-await

14
推荐指数
1
解决办法
3226
查看次数

使用ContinueWith自我继续任务

我有一个需要定期运行的任务.我的第一个实现是:

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)

.net c# task-parallel-library async-await

1
推荐指数
1
解决办法
654
查看次数