csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.9 KiB
110 lines
2.9 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Avalonia.FreeDesktop
|
|
{
|
|
class DBusCallQueue
|
|
{
|
|
private readonly Func<Exception, Task> _errorHandler;
|
|
|
|
class Item
|
|
{
|
|
public Func<Task> Callback;
|
|
public Action<Exception> OnFinish;
|
|
}
|
|
private Queue<Item> _q = new Queue<Item>();
|
|
private bool _processing;
|
|
|
|
public DBusCallQueue(Func<Exception, Task> errorHandler)
|
|
{
|
|
_errorHandler = errorHandler;
|
|
}
|
|
|
|
public void Enqueue(Func<Task> cb)
|
|
{
|
|
_q.Enqueue(new Item
|
|
{
|
|
Callback = cb
|
|
});
|
|
Process();
|
|
}
|
|
|
|
public Task EnqueueAsync(Func<Task> cb)
|
|
{
|
|
var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
_q.Enqueue(new Item
|
|
{
|
|
Callback = cb,
|
|
OnFinish = e =>
|
|
{
|
|
if (e == null)
|
|
tcs.TrySetResult(0);
|
|
else
|
|
tcs.TrySetException(e);
|
|
}
|
|
});
|
|
Process();
|
|
return tcs.Task;
|
|
}
|
|
|
|
public Task<T> EnqueueAsync<T>(Func<Task<T>> cb)
|
|
{
|
|
var tcs = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
_q.Enqueue(new Item
|
|
{
|
|
Callback = async () =>
|
|
{
|
|
var res = await cb();
|
|
tcs.TrySetResult(res);
|
|
},
|
|
OnFinish = e =>
|
|
{
|
|
if (e != null)
|
|
tcs.TrySetException(e);
|
|
}
|
|
});
|
|
Process();
|
|
return tcs.Task;
|
|
}
|
|
|
|
async void Process()
|
|
{
|
|
if(_processing)
|
|
return;
|
|
_processing = true;
|
|
try
|
|
{
|
|
while (_q.Count > 0)
|
|
{
|
|
var item = _q.Dequeue();
|
|
try
|
|
{
|
|
await item.Callback();
|
|
item.OnFinish?.Invoke(null);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
if (item.OnFinish != null)
|
|
item.OnFinish(e);
|
|
else
|
|
await _errorHandler(e);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
_processing = false;
|
|
}
|
|
}
|
|
|
|
public void FailAll()
|
|
{
|
|
while (_q.Count>0)
|
|
{
|
|
var item = _q.Dequeue();
|
|
item.OnFinish?.Invoke(new OperationCanceledException());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|