Added DirectoryObserver
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public class DirectoryObserver
|
||||||
|
{
|
||||||
|
public static async Task<string[]> EnumerateFiles(string path,
|
||||||
|
string[] filter,
|
||||||
|
int count,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
string[] files = [];
|
||||||
|
HashSet<string> extensions = filter.Select(x => $".{x.ToLower()}").ToHashSet();
|
||||||
|
|
||||||
|
bool IsBatchComplete()
|
||||||
|
{
|
||||||
|
files = Directory.EnumerateFiles(path, "*.*", SearchOption.TopDirectoryOnly)
|
||||||
|
.Where(x => extensions.Contains(Path.GetExtension(x).ToLower()))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (files.Length != count)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConcurrentBag<bool> fileAccessResults = [];
|
||||||
|
Parallel.ForEach(files, (file) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using FileStream fileStream = new(file, FileMode.Open, FileAccess.Read, FileShare.None);
|
||||||
|
fileAccessResults.Add(true);
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
fileAccessResults.Add(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return fileAccessResults.All(result => result);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (!IsBatchComplete())
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
await Task.Delay(5000, cancellationToken);
|
||||||
|
}
|
||||||
|
}, cancellationToken);
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,12 +12,12 @@ public interface IMediator
|
|||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
where TMessage : notnull;
|
where TMessage : notnull;
|
||||||
|
|
||||||
IAsyncEnumerable<object?> HandleManyAsync(Type responseType,
|
IAsyncEnumerable<object?> HandleAsyncMany(Type responseType,
|
||||||
object message,
|
object message,
|
||||||
object? key = null,
|
object? key = null,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
IAsyncEnumerable<TResponse?> HandleManyAsync<TMessage, TResponse>(TMessage message,
|
IAsyncEnumerable<TResponse?> HandleAsyncMany<TMessage, TResponse>(TMessage message,
|
||||||
object? key = null,
|
object? key = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
where TMessage : notnull;
|
where TMessage : notnull;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class Mediator(IHandlerProvider handlerProvider,
|
|||||||
MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]);
|
MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]);
|
||||||
if (handleMethod is not null)
|
if (handleMethod is not null)
|
||||||
{
|
{
|
||||||
return await (Task<TResponse?>)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!;
|
return await (Task<TResponse?>)handleMethod.Invoke(handler, [message, cancellationToken])!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ public class Mediator(IHandlerProvider handlerProvider,
|
|||||||
|
|
||||||
if (handleMethod is not null)
|
if (handleMethod is not null)
|
||||||
{
|
{
|
||||||
dynamic task = handleMethod.Invoke(handler, new object[] { message, cancellationToken })!;
|
dynamic task = handleMethod.Invoke(handler, [message, cancellationToken])!;
|
||||||
await task;
|
await task;
|
||||||
|
|
||||||
return task.Result;
|
return task.Result;
|
||||||
@@ -57,35 +57,7 @@ public class Mediator(IHandlerProvider handlerProvider,
|
|||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<object?>> HandleMany(Type responseType,
|
public async IAsyncEnumerable<object?> HandleAsyncMany(Type responseType,
|
||||||
object message,
|
|
||||||
object? key = null,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
List<object?> responses = [];
|
|
||||||
await foreach (object? response in HandleManyAsync(responseType, message, key, cancellationToken))
|
|
||||||
{
|
|
||||||
responses.Add(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
return responses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IList<TResponse?>> HandleMany<TMessage, TResponse>(TMessage message,
|
|
||||||
object? key = null,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TMessage : notnull
|
|
||||||
{
|
|
||||||
List<TResponse?> responses = [];
|
|
||||||
await foreach (TResponse? response in HandleManyAsync<TMessage, TResponse>(message, key, cancellationToken))
|
|
||||||
{
|
|
||||||
responses.Add(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
return responses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async IAsyncEnumerable<object?> HandleManyAsync(Type responseType,
|
|
||||||
object message,
|
object message,
|
||||||
object? key = null,
|
object? key = null,
|
||||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||||
@@ -102,12 +74,12 @@ public class Mediator(IHandlerProvider handlerProvider,
|
|||||||
|
|
||||||
if (handleMethod is not null)
|
if (handleMethod is not null)
|
||||||
{
|
{
|
||||||
yield return await (Task<object?>)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!;
|
yield return await (Task<object?>)handleMethod.Invoke(handler, [message, cancellationToken])!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async IAsyncEnumerable<TResponse?> HandleManyAsync<TMessage, TResponse>(TMessage message,
|
public async IAsyncEnumerable<TResponse?> HandleAsyncMany<TMessage, TResponse>(TMessage message,
|
||||||
object? key = null,
|
object? key = null,
|
||||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||||
where TMessage : notnull
|
where TMessage : notnull
|
||||||
@@ -122,11 +94,38 @@ public class Mediator(IHandlerProvider handlerProvider,
|
|||||||
MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]);
|
MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]);
|
||||||
if (handleMethod is not null)
|
if (handleMethod is not null)
|
||||||
{
|
{
|
||||||
yield return await (Task<TResponse?>)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!;
|
yield return await (Task<TResponse?>)handleMethod.Invoke(handler, [message, cancellationToken])!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<object?>> HandleMany(Type responseType,
|
||||||
|
object message,
|
||||||
|
object? key = null,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
List<object?> responses = [];
|
||||||
|
await foreach (object? response in HandleAsyncMany(responseType, message, key, cancellationToken))
|
||||||
|
{
|
||||||
|
responses.Add(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return responses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<TResponse?>> HandleMany<TMessage, TResponse>(TMessage message,
|
||||||
|
object? key = null,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TMessage : notnull
|
||||||
|
{
|
||||||
|
List<TResponse?> responses = [];
|
||||||
|
await foreach (TResponse? response in HandleAsyncMany<TMessage, TResponse>(message, key, cancellationToken))
|
||||||
|
{
|
||||||
|
responses.Add(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return responses;
|
||||||
|
}
|
||||||
private List<object?> GetHandlers(object message,
|
private List<object?> GetHandlers(object message,
|
||||||
Type handlerWrapperType,
|
Type handlerWrapperType,
|
||||||
object? key)
|
object? key)
|
||||||
@@ -155,8 +154,11 @@ public class Mediator(IHandlerProvider handlerProvider,
|
|||||||
provider.GetServices(handlerWrapperType);
|
provider.GetServices(handlerWrapperType);
|
||||||
AddHandlers(keyedServices);
|
AddHandlers(keyedServices);
|
||||||
|
|
||||||
|
if (key is not null)
|
||||||
|
{
|
||||||
IEnumerable<object?> additionalHandlers = handlerProvider.Get(key);
|
IEnumerable<object?> additionalHandlers = handlerProvider.Get(key);
|
||||||
AddHandlers(additionalHandlers);
|
AddHandlers(additionalHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
return handlers.SelectMany(entry => entry.Value).ToList();
|
return handlers.SelectMany(entry => entry.Value).ToList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public static class MediatorExtensions
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
x:CompileBindings="True">
|
x:CompileBindings="True">
|
||||||
<ControlTheme x:Key="{x:Type TabStrip}" TargetType="TabStrip">
|
<ControlTheme x:Key="{x:Type TabStrip}" TargetType="TabStrip">
|
||||||
<Setter Property="MinHeight" Value="32" />
|
<Setter Property="MinHeight" Value="36" />
|
||||||
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
|
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
|
||||||
<Setter Property="Background" Value="{DynamicResource ControlAltFillColorSecondaryBrush}" />
|
<Setter Property="Background" Value="{DynamicResource ControlAltFillColorSecondaryBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource ControlStrokeColorDefaultBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource ControlStrokeColorDefaultBrush}" />
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<Setter Property="BorderBrush" Value="{DynamicResource ControlFillColorTransparentBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource ControlFillColorTransparentBrush}" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
|
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
|
||||||
<Setter Property="FontWeight" Value="Normal" />
|
<Setter Property="FontWeight" Value="Normal" />
|
||||||
<Setter Property="Height" Value="32" />
|
<Setter Property="MinHeight" Value="36" />
|
||||||
<Setter Property="MinWidth" Value="60" />
|
<Setter Property="MinWidth" Value="60" />
|
||||||
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
|
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
|
||||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||||
@@ -66,7 +66,6 @@
|
|||||||
<BrushTransition Property="Background" Duration="00:00:00.083" />
|
<BrushTransition Property="Background" Duration="00:00:00.083" />
|
||||||
</Transitions>
|
</Transitions>
|
||||||
</Border.Transitions>
|
</Border.Transitions>
|
||||||
|
|
||||||
<Panel>
|
<Panel>
|
||||||
<Border
|
<Border
|
||||||
Name="Hover"
|
Name="Hover"
|
||||||
@@ -83,7 +82,6 @@
|
|||||||
</Transitions>
|
</Transitions>
|
||||||
</Border.Transitions>
|
</Border.Transitions>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<ContentPresenter
|
<ContentPresenter
|
||||||
Name="PART_ContentPresenter"
|
Name="PART_ContentPresenter"
|
||||||
Margin="11,5,11,6"
|
Margin="11,5,11,6"
|
||||||
@@ -95,7 +93,6 @@
|
|||||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||||
FontWeight="{TemplateBinding FontWeight}"
|
FontWeight="{TemplateBinding FontWeight}"
|
||||||
Foreground="{TemplateBinding Foreground}" />
|
Foreground="{TemplateBinding Foreground}" />
|
||||||
|
|
||||||
<Rectangle
|
<Rectangle
|
||||||
Name="Pill"
|
Name="Pill"
|
||||||
Width="4"
|
Width="4"
|
||||||
@@ -122,7 +119,6 @@
|
|||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
|
||||||
|
|
||||||
<Style Selector="^:pointerover">
|
<Style Selector="^:pointerover">
|
||||||
<Style Selector="^ /template/ Border#Hover">
|
<Style Selector="^ /template/ Border#Hover">
|
||||||
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
|
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
|
||||||
|
|||||||
Reference in New Issue
Block a user