Однако ConnectFtpAsync и ConnectDbAsync кроме DoAsync приводит к зависанию проекта WPF, когда количество задач превышает предел семафора.
ButtonPressedAsync(), который является самым внешним вызовом, не использует ConfigurationAwait(false) и ConfigurationAwait(false), используемые при внутреннем вызове, не должно иметь значения.
Удаление ConfigureAwait(false) из внутренних вызовов не решило проблему.
Удаление семафора или непревышение лимита семафора решило проблему проблема.
Для данного кода используются FluentFTP и Oracle.
3 примера тестируются отдельно.
- Почему ConnectFtpAsync и ConnectDbAsync блокируют проект WPF?
- Почему DoAsync не блокирует проект WPF?
{
await ButtonPressedAsync();
}
private static async Task ButtonPressedAsync()
{
try
{
var connectionLimit = 4;
var smph = new Semaphore(connectionLimit, connectionLimit);
var tasks = new List();
for (var i = 0; i < connectionLimit + 1; ++i)
tasks.Add(DoAsync(smph));
//for (var i = 0; i < connectionLimit + 1; ++i)
// tasks.Add(ConnectFtpAsync(smph));
//for (var i = 0; i < connectionLimit + 1; ++i)
// tasks.Add(ConnectDbAsync(smph));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
catch (Exception ex)
{
;
}
}
private static async Task DoAsync(Semaphore smph)
{
smph.WaitOne();
await Task.Delay(500).ConfigureAwait(false);
smph.Release();
}
private static async Task ConnectFtpAsync(Semaphore smph)
{
smph.WaitOne();
var ftpConnection = new AsyncFtpClient(
host: "ip",
port: 21,
user: "id",
pass: "pswd");
await ftpConnection.Connect().ConfigureAwait(false);
smph.Release();
}
private static async Task ConnectDbAsync(Semaphore smph)
{
smph.WaitOne();
var credential = "credential";
using var dbConnection = new OracleConnection(credential);
await dbConnection.OpenAsync().ConfigureAwait(false);
await dbConnection.CloseAsync().ConfigureAwait(false);
smph.Release();
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... ock-on-wpf