2023-09-12 16:29:43 +08:00

89 lines
2.1 KiB
C#

using Foundation;
namespace Blahblah.Library.Network;
abstract class ContentTask<T, TResult> : NetworkTask
{
public StepHandler<T>? Step { get; set; }
protected virtual bool AllowDefaultResult => false;
protected TaskCompletionSource<NetworkResult<TResult>>? taskSource;
protected long expectedContentLength;
protected ContentTask(string url, TaskCompletionSource<NetworkResult<TResult>> 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 OnResponded(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;
}
}
}