using Foundation; namespace Blahblah.Library.Network; public abstract class ContentTask : NetworkTask { public StepHandler? Step { get; set; } protected virtual bool AllowDefaultResult => false; protected TaskCompletionSource>? taskSource; protected long expectedContentLength; protected ContentTask(string url, TaskCompletionSource> source, CancellationToken token) : base(url, token) { taskSource = source ?? throw new ArgumentNullException(nameof(source)); } protected override void OnCancelled() { taskSource?.TrySetCanceled(); } protected override void OnException(Exception ex) { taskSource?.TrySetResult(ex); } public override bool OnResponsed(NSHttpUrlResponse response) { expectedContentLength = response.ExpectedContentLength; return true; } protected virtual T? Update(float progress) { return default; } public override void OnReceived(int length) { if (Step != null) { if (Data == null) { Step(0f, default); } else { float progress = (float)Data.Length / expectedContentLength; var update = Update(progress); Step(progress, update); } } } protected virtual TResult? Completed(NSHttpUrlResponse? response) { throw new NotImplementedException(); } protected override void OnCompleted(NSHttpUrlResponse? response) { try { var result = Completed(response); if (result == null && !AllowDefaultResult) { throw new NullReferenceException("Result is null"); } taskSource?.TrySetResult(result); } catch (Exception ex) { OnException(ex); } } protected override void Disposing() { if (taskSource?.Task.IsCanceled == false) { taskSource.TrySetCanceled(); taskSource = null; } } }