c# - 如何在 C# 异步任务中异步等待特定条件

标签 c# multithreading asynchronous blocking

我正在寻找一种简单而有效的异步方式(等待/阻止),而无需在异步任务方法中进行轮询。

我创建了一个简单的伪代码情况如下:

private var queue = new ConcurrentQueue<Command>();

        // Function called by program 
        public async Task<String> GetNameAsync(int id)
        {
            //Build Command
            var Command = new Command(id);

            //Enqueue Command to concurrent queue
            queue.enqueue(command);

            //Wait for command to finnish executing, posibly supply a timeout   
            await command.CompleteCondition

            //Once command has completed or timed out return the result of the task.
            return command.Response.getString();
        }


        //Continiously runs in its own thread
        private void MainThread()
        {
            while(mustRun)
            {
                if(queue.Any())
                {
                    //Get command from queue if there is one
                    var command = queue.dequeue();

                    //Execute command
                    var result = ExecuteCcommand(command);

                    //Set Command Done with result (so the blocking async task can continue:
                    //TODO: 

                }else{
                Thread.Sleep(100);          
            }
        }

我遗漏了我不知道的机制,但本质上我需要将某种锁与命令一起传递给主线程,然后主线程一旦它通知异步任务已完成,以便任务可以继续。

我确信一定有某种类型的 c# 机制,专门设计用于与 c# 异步任务库一起使用。我显然不知道它并且从未使用过它。您建议我使用什么?

最佳答案

最简单的方法是使用TaskCompletionSource。例如:

public class Command
{
  private readonly TaskCompletionSource<string> _tcs = new TaskCompletionSource<string>();

  public Task<string> ExecuteAsync()
  {
    return _tcs.Task;
  }

  internal void ExecuteCommand()
  {
    if (_tcs.Task.IsCompleted) return;

    try
    {
      // Do your work...

      _tcs.SetResult(result);
    }
    catch (Exception ex) 
    {
      _tcs.SetException(ex);
    }
  }
}

执行命令时,只需var result = wait ExecuteAsync();。在您的工作线程中,只需执行 ExecuteCommand();

关于c# - 如何在 C# 异步任务中异步等待特定条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32455985/

相关文章:

c# - 从 Azure IoT 中心获取设备列表

c# - Emgu 无法在 IIS 服务器中找到 cvextern

c# - asp.hyperlink in gridview Format 0 as null

ios - UIDocument & NSFileWrapper 架构和性能

javascript - 我应该将 DOM 操作 JS 脚本放在 `<head>` 中还是在结束 `</body>` 之前?

c# - N-Hibernate 中的长字符串与 Oracle 导致错误

java - 在 Java 中实现这种线程/事件行为的最佳方式是什么?

java - 按顺序处理异步事件和发布结果

javascript - promise 中的超时循环在 promise 解决后永远不会执行?

multithreading - libevent/epoll工作线程数?