Reputation: 9
I want connect to DB through anytime Client click Button. When Client clicks button many time with different ConnectionString. Now I want to return only last Connection created by Client. Therefore, I must cancel last Task and created new Task. The Problem is how can I cancel a Task after I call Task.wait() use CancellationToken? Because when I not yet call wait()
, Task Status will be WaitForActive, so I will never can receive result. Please help me solve that case. My draft code below:
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();
}
}
Upvotes: 0
Views: 321
Reputation: 5102
Don't use wait on tasks because of freeze main thread.
You can use a dictionary of tasks and cancellation tokens to manage your tasks like this(I just simulate your methods):
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";
}
Upvotes: 1