Я разрабатываю приложение Maui, которое загружает файлы в хранилище Azure Blob. Приложение имеет переключатель переключателя для загрузки запуска/остановки, но я сталкиваюсь с проблемами с отзывчивостью пользовательского интерфейса во время отмены и обработки исключений.
Текущая реализация:
< /ul>
Управление переключателя >
реализует одновременную загрузку с помощью Semaphoreslim
-может отменить как в процессе, так и в ожидании задач загрузки < /li>
< /ul>
Проблемы: < /li>
< /ul>
UI становится без реагирования при отмене загрузки < /li>
Консоль затоплен TaskCanceleDexceptions < /li>
Необходимо обрабатывать отмену отдельно для загрузки в процессах по сравнению с ожидающими загрузками < /li>
< /ul>
// Toggle switch handler
partial void OnIsSyncOnChanged(bool oldValue, bool newValue)
{
if (newValue)
{
_gtecSyncCts?.Cancel();
_gtecSyncCts?.Dispose();
_gtecSyncCts = new CancellationTokenSource();
Task.Run(async () => StartSyncAsync(_gtecSyncCts.Token));
}
else
{
Task.Run(async () =>
{
await StopSync();
ProgressMessage = "Sync stopped by user";
});
}
}
// Main sync method
private async Task StartSyncAsync(CancellationToken token)
{
try
{
ActiveTransfers.Clear();
var filesToUpload = await _fileMetadataManager.GetFilesToUploadAsync(token);
await PrepareUploadsAsync(filesToUpload, new Progress(message => UpdateProgressUI(message, 0)));
await UploadFilesAsync(token, new Progress(message => UpdateProgressUI(message, 0)));
}
catch (OperationCanceledException)
{
Debug.WriteLine("Sync operation was canceled.");
UpdateProgressUI("Sync operation was canceled", 0);
await CancelPendingUploadsAsync();
}
}
// Upload preparation
private async Task PrepareUploadsAsync(List filesToUpload, IProgress progress)
{
ActiveTransfers.Clear();
int totalFiles = filesToUpload.Count;
for (int i = 0; i < totalFiles; i++)
{
var file = filesToUpload;
var blobClient = _uploadManager.GetBlobClient(
file.destination_folder,
file.filename,
file.FileExtension
);
var uploadViewModel = new FileUploadViewModel(file, blobClient);
uploadViewModel.UploadStateChanged += OnUploadStateChanged;
ActiveTransfers.Add(uploadViewModel);
progress.Report($"Prepared {i + 1}/{totalFiles} files for upload");
}
}
// Concurrent upload handling
private async Task UploadFilesAsync(CancellationToken token, IProgress progress)
{
using var semaphore = new SemaphoreSlim(4);
var tasks = new List();
var completedUploads = 0;
var totalUploads = ActiveTransfers.Count;
foreach (var vm in ActiveTransfers)
{
await semaphore.WaitAsync(token);
tasks.Add(Task.Run(async () =>
{
try
{
await vm.StartUploadAsync(token);
var completed = Interlocked.Increment(ref completedUploads);
}
finally
{
semaphore.Release();
}
}));
}
await Task.WhenAll(tasks);
}
// Individual file upload
public async Task StartUploadAsync(CancellationToken externalToken)
{
_cts = CancellationTokenSource.CreateLinkedTokenSource(externalToken);
try
{
await UpdateState(UploadState.Checking);
var blobExists = await BlobClient.ExistsAsync(_cts.Token);
if (blobExists)
{
FileMetadata.BlobStoragePath = BlobClient.Uri.ToString();
await UpdateState(UploadState.AlreadyUploaded);
return;
}
await UpdateState(UploadState.Uploading);
var options = new BlobUploadOptions
{
TransferOptions = new StorageTransferOptions
{
MaximumConcurrency = 8,
MaximumTransferSize = 4 * 1024 * 1024,
InitialTransferSize = 4 * 1024 * 1024
},
ProgressHandler = new Progress(ReportProgress)
};
await BlobClient.UploadAsync(FileMetadata.FilePath, options, _cts.Token);
FileMetadata.BlobStoragePath = BlobClient.Uri.ToString();
await UpdateState(UploadState.Completed);
}
catch (OperationCanceledException)
{
await UpdateState(UploadState.Cancelled, "Upload was cancelled by the user");
}
catch (Exception ex)
{
await UpdateState(UploadState.Failed, ex.Message);
}
}
< /code>
Каким -то образом этот дизайн управляет двумя работами, но пользовательский интерфейс становится действительно без реагирования, когда я выключаю выключатель, выбрасывая отмену, и консоль забивается исключениями:
Исключено: 'Система. Threading.tasks.taskcanceleDexception 'in system.private.corelib.dll < /p>
Во -вторых, в этом случае мне нужно обрабатывать сериал. обрабатываются методом CancelpendingUploadSasync (). < /p>
Я также уверен, что я злоупотребляю задачей. мой startsyncasync уже выпущен в отдельной потоке Lord ai, предложил использовать его также в uploadfilessync (), чтобы обедать каждую задачу загрузки в одном потоке. Я не смог хорошо использовать < /p>
TransferOptions = new StorageTransferOptions
{
MaximumConcurrency = 8,
< /code>
в Azure API. Даже с этим звонком, если я начну 100 загрузки, все они начнут одновременно
Может быть, я неправильно понял цель максимальной концентрации Proprierty < /p>
Подробнее здесь: https://stackoverflow.com/questions/794 ... ken-source
Отмена нескольких задач из одного источника токена отмены ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Отмена фона выполнения задачи, когда пользователь нажимает на кнопку «Отмена
Anonymous » » в форуме JAVA - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Отмена фона выполнения задачи, когда пользователь нажимает на кнопку «Отмена
Anonymous » » в форуме JAVA - 0 Ответы
- 25 Просмотры
-
Последнее сообщение Anonymous
-