如何在 .NET 中的 Task.Wait() 之后取消正在运行的 OpenAsync()?

问题描述

我想随时通过客户端单击按钮连接到数据库。当客户端使用不同的 ConnectionString 多次单击按钮时。现在我只想返回客户端创建的最后一个连接。因此,我必须取消上一个任务并创建新任务。问题是如何在调用 Task.wait() 使用 CancellationToken 后取消任务?因为当我还没有调用wait()时,任务状态将是WaitForActive,所以我永远无法收到结果。请帮我解决那个案子。我的草稿代码如下:

    private sqlConnection _connection = null;
    private CancellationTokenSource _source = null;
    private Task<string> _result = null;
    
    public Task<string> GetStatusAsync(string connectionString)
    {
        if (_source == null)
            _source = new CancellationTokenSource();
        if (_connection != null && _connection.State == ConnectionState.Connecting)
        {
            _source.Cancel();
            _source = new CancellationTokenSource();
        }

        _result = ConnectDatabaseAsync(connectionString.Trim(),_source.Token);
        _result.Wait();
        return _result;
    }

    private async Task<string> ConnectDatabaseAsync(string connectionString,CancellationToken cancellationToken)
    {                        
        if (_connection == null)
            _connection = new sqlConnection();
        try
        {
            _connection.ConnectionString = connectionString;
            await _connection.OpenAsync(cancellationToken);
            return "ok";
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
        finally
        {
            if (_connection.State == ConnectionState.Open)
                _connection.Close();
        }
    }

解决方法

不要使用等待任务,因为冻结主线程。

你可以使用任务字典和取消令牌来管理你的任务(我只是模拟你的方法):

      private static readonly Dictionary<Task,CancellationTokenSource> Tasks = new Dictionary<Task,CancellationTokenSource>();
      public async Task<string> GetStatusAsync()
        {
            var source = new CancellationTokenSource();
            var task = ConnectDatabaseAsync("YourConnection",source.Token);

            if (Tasks.Any())
                foreach (var item in Tasks)
                {
                    if (!item.Key.IsCompleted && !item.Value.IsCancellationRequested)
                        item.Value.Cancel();
                }

            Tasks.Add(task,source);

            await task;

            return task.Result;
        }

        private async Task<string> ConnectDatabaseAsync(string connection,CancellationToken token)
        {
            await Task.Delay(10000,token);

            return "Ok";
        }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...