Skip to content

Instantly share code, notes, and snippets.

View in-async's full-sized avatar

inasync in-async

View GitHub Profile
@in-async
in-async / UriComparer.cs
Created January 20, 2024 08:56
クエリ パラメータ順に依存しない `Uri` 比較子 (と、クエリ値がカンマ区切りのコレクションの場合に、そちらも順序非依存とする為のアイテム比較子) の仮組み
internal sealed class UriComparer : IEqualityComparer<Uri> {
private readonly IEqualityComparer<KeyValuePair<string, StringValues>> _queryComparer;
public UriComparer(IEqualityComparer<KeyValuePair<string, StringValues>>? queryComparer = null) {
_queryComparer = queryComparer ?? EqualityComparer<KeyValuePair<string, StringValues>>.Default;
}
public bool Equals(Uri? x, Uri? y) {
if (x == y) { return true; }
if (x is null || y is null) { return false; }
@in-async
in-async / Quiz:TaskRun_with_OperationCanceledException.cs
Last active October 15, 2023 04:39
どっちも同じように OperationCanceledException を投げてるだけなのに、 Task.Status が異なるのなーんでだ
CancellationToken ct = new CancellationTokenSource(0).Token;
Task task1 = Task.Run(() => throw new OperationCanceledException(ct));
Task task2 = Task.Run(() => ct.ThrowIfCancellationRequested());
Task.WhenAll(task1, task2).ContinueWith(_ => {
task1.Status.Dump(); // Canceled
task2.Status.Dump(); // Faulted
});
@in-async
in-async / SpanSplitExtensions.cs
Created October 5, 2023 10:07
.NET 8 未満向け MemoryExtensions.Split もどき
public static class SpanSplitExtensions {
public static int Split<T>(this ReadOnlySpan<T> source, Span<Range> destination, T separator) where T: IEquatable<T> {
return Split(source, destination, new ReadOnlySpan<T>(separator));
}
public static int Split<T>(this ReadOnlySpan<T> source, Span<Range> destination, ReadOnlySpan<T> separator) where T: IEquatable<T> {
int rangesWritten = 0;
int offset = 0;
public static class ObjectInvokeExtensions {
public static TResult Invoke<T, TResult>(this T value, Func<T, TResult> func) {
if (func is null) { throw new ArgumentNullException(nameof(func)); }
return func(value);
}
public static void Invoke<T>(this T value, Action<T> action) {
if (action is null) { throw new ArgumentNullException(nameof(action)); }
action(value);
@in-async
in-async / TaskCompletionSource-DeadLock.cs
Last active September 20, 2023 08:09
`TaskCompletionSource<T>` でデッドロックする例
TaskCompletionSource<object?> tcs = new(
// NOTE: RunContinuationsAsynchronously を付けるとデッドロックしない(非同期に継続される)
// TaskCreationOptions.RunContinuationsAsynchronously
);
ManualResetEventSlim mre = new();
_ = Task.Run(() => {
Console.WriteLine("Start background");
tcs.TrySetResult(null); // 2
mre.Set(); // (4)
@in-async
in-async / src-1.TypedLogger.cs
Last active August 2, 2023 13:11
ログを外部リポジトリに書き込む為のクラス。
using System.Threading.Channels;
namespace Commons;
public interface ITypedLogger<T> {
void Log(T log);
}
public abstract class TypedLogger<T> : ITypedLogger<T>, IDisposable, IAsyncDisposable {
@in-async
in-async / Later.cs
Last active October 13, 2023 11:29
定期的に自動更新される値を表すクラス。
/// <summary>
/// 定期的に自動更新される値を表すクラス。
/// </summary>
public sealed class Later<T> : IDisposable {
private readonly CancellationTokenSource _disposingCts = new();
private readonly CancellationTokenSource _stoppingCts;
private Task<T> _valueTask;
public Later(Func<CancellationToken, Task<T>> factory, TimeSpan period, CancellationToken stoppingToken = default)
: this(factory, period, LaterErrorHandling.Capture, stoppingToken) {
public static class DistributedCacheExtensions {
public static async Task<T> GetOrSetAsync<T>(this IDistributedCache cache
, string key
, Func<byte[], T> deserialize
, Func<Task<(T, byte[], DistributedCacheEntryOptions options)>> factory
, CancellationToken token = default
) {
if (cache is null) { throw new ArgumentNullException(nameof(cache)); }
if (key is null) { throw new ArgumentNullException(nameof(key)); }
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
namespace Commons {
/// <summary>
/// <see cref="BackgroundService.ExecuteAsync(CancellationToken)"/> で生じた例外が全て Host でハンドルされるよう対応した <see cref="BackgroundService"/> 。
/// </summary>
/// <remarks>
@in-async
in-async / TtlLazy.cs
Last active June 24, 2022 01:35
期限付き Lazy
public class TtlLazy<T> {
private readonly Func<T> _factory;
private readonly TimeSpan _ttl;
private T _value = default!;
private bool _initialized;
private object? _lock;
public TtlLazy(Func<T> factory, TimeSpan ttl) {
_factory = factory ?? throw new ArgumentNullException(nameof(factory));