Doombox
Doombox
CC#
Created by Doombox on 2/14/2023 in #help
❔ ✅ System.Text.Json paths
Does STJ support paths in some way? In NSJ I would use a ContractResolver and a custom attribute to handle this Essentially I want to access this (pointlessly) nested property
Time: {
"time": "1:27.452"
},
Time: {
"time": "1:27.452"
},
in NSJ I could define this attribute[JsonPathProperty("Time.time")] and use a ContractResolver to drag the value back up, preventing needless object bloat.
12 replies
CC#
Created by Doombox on 8/27/2022 in #help
Correctly reading tabs from text file. [Answered]
I have some Markdown files that are just this
- Some Item
- Some Tabbed Item
- Some Item
- Some Tabbed Item
and I'm reading them like this
if (!SemanticVersion.TryParse(file[path.Length..^3], out var semVer)) continue;
await using var stream = _assembly.GetManifestResourceStream(file);
if (stream is null) continue;
using var reader = new StreamReader(stream);
changelogs.Add(semVer, await reader.ReadToEndAsync());
if (!SemanticVersion.TryParse(file[path.Length..^3], out var semVer)) continue;
await using var stream = _assembly.GetManifestResourceStream(file);
if (stream is null) continue;
using var reader = new StreamReader(stream);
changelogs.Add(semVer, await reader.ReadToEndAsync());
however the tabbed items are having their tabs stripped from them and the output is just a bunch of strings split by \r\n, not sure how I'm supposed to read it correctly to preserve the tabs
4 replies
CC#
Created by Doombox on 8/24/2022 in #help
WPF Handling crashes more gracefully. [Answered]
I'm currently using this setup which correctly logs and displays feedback correctly, however after the messagebox is closed the application window hangs around for a few seconds completely locked up, calling .Dispose() to clean up the NotifyIcon in the tray more than doubles the time. Is there a way to force the window closed?
private bool _hasProvidedCrashFeedback;

private void CurrentDomainOnFirstChanceException(object sender, FirstChanceExceptionEventArgs e) =>
HandleException(e.Exception);

protected override void OnUnhandledException(DispatcherUnhandledExceptionEventArgs e) =>
HandleException(e.Exception);

private void HandleException(Exception e)
{
_log.Fatal(e, "");
if (_hasProvidedCrashFeedback) return;
_hasProvidedCrashFeedback = true;
Dispose(); // this call doubles the time the window hangs around
MessageBox.Show("See C:\\Users\\USERNAME\\AppData\\Roaming\\F1Desktop\\Logs for technical information.",
"F1 Desktop Has Crashed Unexpectedly");
}

public override void Dispose()
{
GC.SuppressFinalize(this);
_icon.Dispose();
JobManager.Stop();
base.Dispose();
}
private bool _hasProvidedCrashFeedback;

private void CurrentDomainOnFirstChanceException(object sender, FirstChanceExceptionEventArgs e) =>
HandleException(e.Exception);

protected override void OnUnhandledException(DispatcherUnhandledExceptionEventArgs e) =>
HandleException(e.Exception);

private void HandleException(Exception e)
{
_log.Fatal(e, "");
if (_hasProvidedCrashFeedback) return;
_hasProvidedCrashFeedback = true;
Dispose(); // this call doubles the time the window hangs around
MessageBox.Show("See C:\\Users\\USERNAME\\AppData\\Roaming\\F1Desktop\\Logs for technical information.",
"F1 Desktop Has Crashed Unexpectedly");
}

public override void Dispose()
{
GC.SuppressFinalize(this);
_icon.Dispose();
JobManager.Stop();
base.Dispose();
}
12 replies
CC#
Created by Doombox on 8/23/2022 in #help
Using multiple RateLimiters correctly. [Answered]
I'm wrapping an API which requires no more than 4 requests per second and 200 per hour, I've got a setup like this
_hourlyRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
200, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromHours(1)));
_secondRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
4, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromSeconds(1)));
// ...
public async Task Test(int testNumber)
{
var hourly = _hourlyRateLimiter.WaitAsync();
var second = _secondRateLimiter.WaitAsync();
await ValueTaskExtensions.WhenAll(hourly, second);
Console.WriteLine(testNumber);
}
_hourlyRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
200, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromHours(1)));
_secondRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
4, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromSeconds(1)));
// ...
public async Task Test(int testNumber)
{
var hourly = _hourlyRateLimiter.WaitAsync();
var second = _secondRateLimiter.WaitAsync();
await ValueTaskExtensions.WhenAll(hourly, second);
Console.WriteLine(testNumber);
}
this works well if you await each call of Test, however if you try something like this...
var tasks = new List<Task>();
for (var i = 0; i < 250; i++)
tasks.Add(Test(i));
await Task.WhenAll(tasks);
var tasks = new List<Task>();
for (var i = 0; i < 250; i++)
tasks.Add(Test(i));
await Task.WhenAll(tasks);
the rate limiter seems to break, have I written this poorly or is this just an issue with concurrency in the library?
5 replies
CC#
Created by Doombox on 8/17/2022 in #help
Creating an installer for an app. [Answered]
Bizarrely this is something I've never actually bothered with, but what's the best way to create an installer that publishes + bundles all your projects together? I have a WPF app and a 2nd CLI tool for updating the WPF app.
32 replies
CC#
Created by Doombox on 8/14/2022 in #help
JsonSerializer.DeserializeAsync() randomly hangs indefinitely [Answered]
private static async Task<T> TryReadDataFromFile<T>(string basePath) where T : class
{
var filepath = GetFilePath<T>(basePath);
if (!File.Exists(filepath)) return null;
await using var filestream = File.Open(filepath, FileMode.Open);
var res = await JsonSerializer.DeserializeAsync<T>(filestream); // This line
await filestream.DisposeAsync();
return res;
}
private static async Task<T> TryReadDataFromFile<T>(string basePath) where T : class
{
var filepath = GetFilePath<T>(basePath);
if (!File.Exists(filepath)) return null;
await using var filestream = File.Open(filepath, FileMode.Open);
var res = await JsonSerializer.DeserializeAsync<T>(filestream); // This line
await filestream.DisposeAsync();
return res;
}
System.Text.Json's DeserializeAsync seems to (entirely at random) decide to hang indefinitely, throws no exceptions or anything in the process which is odd, it's always the same file in AppData that causes it to hang.
57 replies