Mayka
Mayka
CC#
Created by Mekasu0124 on 3/2/2024 in #help
✅ Cannot Get Rid Of Individual Borders On TextBox Avalonia
Also, if you don’t necessarily want to apply a style to every instance of an element, style classes can be very helpful. https://docs.avaloniaui.net/docs/basics/user-interface/styling/style-classes
11 replies
CC#
Created by Mekasu0124 on 3/2/2024 in #help
✅ Cannot Get Rid Of Individual Borders On TextBox Avalonia
11 replies
CC#
Created by Mekasu0124 on 3/2/2024 in #help
✅ Cannot Get Rid Of Individual Borders On TextBox Avalonia
For example, if you just want to target the border on grid elements, you can do this: <Style Selector="Grid > Border">
11 replies
CC#
Created by Mekasu0124 on 3/2/2024 in #help
✅ Cannot Get Rid Of Individual Borders On TextBox Avalonia
@Mekasu0124 under styles you’re adding a style selector for Border. That’s gonna apply to anything with a border, including text boxes. If you want to target a border for a specific kind of object you would need to specify that in the style.
11 replies
CC#
Created by Mekasu0124 on 3/2/2024 in #help
✅ Cannot Get Rid Of Individual Borders On TextBox Avalonia
@Mekasu0124 can you supply the code for your view model class as well?
11 replies
CC#
Created by Mayka on 2/21/2024 in #help
✅ Lag after closing folder dialog in console application
@leowest after extensive troubleshooting, OneDrive seems likely to have been the culprit, possibly due to a corrupted SharePoint shortcut. Since removing it, File Explorer is auto-synching again with file system changes, and my C# code is no longer hanging after I’ve closed the folder dialog. Thank you very much for your help with this! Determining it was a setup issue rather than a C# issue helped lead me down a path toward a solution.
18 replies
CC#
Created by Mayka on 2/21/2024 in #help
✅ Lag after closing folder dialog in console application
@leowest this is a work computer, but it’s definitely an issue with mine specifically. I had my coworker try the same exe and they didn’t have a delay either. UGH!! I hate when I chase my tail after the completely wrong thing. My hunch tells me it has to do with the same issue I experience where if I create a new folder or delete a file in File Explorer, the changes never seem to show up for me until I hit the Refresh button. I thought maybe it was my local icon cache, but deleting that didn’t fix the issue.
18 replies
CC#
Created by Mayka on 2/21/2024 in #help
✅ Lag after closing folder dialog in console application
@leowest well we’re actually on the exact same OS build, so I guess that’s not it :OOF:
18 replies
CC#
Created by Mayka on 2/21/2024 in #help
✅ Lag after closing folder dialog in console application
@leowest what OS version are you on? Trying to figure out if this is an OS issue.
18 replies
CC#
Created by Mayka on 2/21/2024 in #help
✅ Lag after closing folder dialog in console application
No description
18 replies
CC#
Created by Mayka on 2/9/2024 in #help
ILogger Dependency Injection for Libraries
@TeBeCo, I like that a lot, it’s very clean. For internal classes which are only instantiated inside the library and not available to callers, would the best practice be for those to take the non-generic ILogger and have whichever class instantiates them pass in its own logger, since its type is meant to truly be internal and shouldn’t be leaking its context into logs anyhow? e.g.,
public class FooRed(ILogger<FooRed> logger) : IFoo
{
    private readonly FooColor _fooColor = new("red", logger);
 
    public void DoSomething()
    {
        logger.LogInformation("I'm {fooColor}!", _fooColor.Color);
    }
}
 
internal class FooColor
{
    public FooColor(string color, ILogger logger)
    {
        Color = color;
        logger.LogTrace("Creating a new {Color} ColorFoo", color);
    }
 
    public string Color { get; }
}
public class FooRed(ILogger<FooRed> logger) : IFoo
{
    private readonly FooColor _fooColor = new("red", logger);
 
    public void DoSomething()
    {
        logger.LogInformation("I'm {fooColor}!", _fooColor.Color);
    }
}
 
internal class FooColor
{
    public FooColor(string color, ILogger logger)
    {
        Color = color;
        logger.LogTrace("Creating a new {Color} ColorFoo", color);
    }
 
    public string Color { get; }
}
75 replies
CC#
Created by Mayka on 2/9/2024 in #help
ILogger Dependency Injection for Libraries
@TeBeCo this code will be in a library with the only point of entry being FooFactory, so I would not be able to register FooRed or FooBlue. In that case are you saying I would want to inject a factory all the way down like this?
using LogInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Serilog;
using ILogger = Microsoft.Extensions.Logging.ILogger;

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {SourceContext}] {Message:lj}{NewLine}{Exception}"
)
.CreateLogger();

using ServiceProvider serviceProvider = new ServiceCollection()
.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true))
.AddSingleton<FooFactory>()
.BuildServiceProvider();

var fooFactory = serviceProvider.GetRequiredService<FooFactory>();
fooFactory.CreateFoo("red").DoSomething();
fooFactory.CreateFoo("blue").DoSomething();

Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();

namespace LogInjection
{
public class FooFactory(ILoggerFactory? loggerFactory = null)
{
private readonly ILogger _logger = loggerFactory is not null
? loggerFactory.CreateLogger<FooFactory>()
: NullLogger<FooFactory>.Instance;

public IFoo CreateFoo(string type)
{
_logger.LogInformation("Creating a new {Type}", type);

return type switch
{
"red" => new FooRed(loggerFactory),
"blue" => new FooBlue(loggerFactory),
_ => throw new ArgumentException("Unknown type", nameof(type)),
};
}
}

public interface IFoo
{
void DoSomething();
}

internal class FooRed(ILoggerFactory? loggerFactory) : IFoo
{
private readonly ILogger _logger = loggerFactory is not null
? loggerFactory.CreateLogger<FooRed>()
: NullLogger<FooRed>.Instance;

public void DoSomething()
{
_logger.LogInformation("I'm red!");
}
}

internal class FooBlue(ILoggerFactory? loggerFactory) : IFoo
{
private readonly ILogger _logger = loggerFactory is not null
? loggerFactory.CreateLogger<FooBlue>()
: NullLogger<FooBlue>.Instance;

public void DoSomething()
{
_logger.LogInformation("I'm blue!");
}
}
}
using LogInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Serilog;
using ILogger = Microsoft.Extensions.Logging.ILogger;

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {SourceContext}] {Message:lj}{NewLine}{Exception}"
)
.CreateLogger();

using ServiceProvider serviceProvider = new ServiceCollection()
.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true))
.AddSingleton<FooFactory>()
.BuildServiceProvider();

var fooFactory = serviceProvider.GetRequiredService<FooFactory>();
fooFactory.CreateFoo("red").DoSomething();
fooFactory.CreateFoo("blue").DoSomething();

Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();

namespace LogInjection
{
public class FooFactory(ILoggerFactory? loggerFactory = null)
{
private readonly ILogger _logger = loggerFactory is not null
? loggerFactory.CreateLogger<FooFactory>()
: NullLogger<FooFactory>.Instance;

public IFoo CreateFoo(string type)
{
_logger.LogInformation("Creating a new {Type}", type);

return type switch
{
"red" => new FooRed(loggerFactory),
"blue" => new FooBlue(loggerFactory),
_ => throw new ArgumentException("Unknown type", nameof(type)),
};
}
}

public interface IFoo
{
void DoSomething();
}

internal class FooRed(ILoggerFactory? loggerFactory) : IFoo
{
private readonly ILogger _logger = loggerFactory is not null
? loggerFactory.CreateLogger<FooRed>()
: NullLogger<FooRed>.Instance;

public void DoSomething()
{
_logger.LogInformation("I'm red!");
}
}

internal class FooBlue(ILoggerFactory? loggerFactory) : IFoo
{
private readonly ILogger _logger = loggerFactory is not null
? loggerFactory.CreateLogger<FooBlue>()
: NullLogger<FooBlue>.Instance;

public void DoSomething()
{
_logger.LogInformation("I'm blue!");
}
}
}
75 replies
CC#
Created by Mayka on 2/12/2024 in #help
Properly locking the console in async code
@cap5lut I did not know about Spectre.Console, that’s awesome info thanks! It doesn’t sound like their progress bar will work for my particular use case, per the below, but I may use some of the other features they offer.
The progress display is not thread safe, and using it together with other interactive components such as prompts, status displays or other progress displays are not supported.
16 replies
CC#
Created by Mayka on 2/12/2024 in #help
Properly locking the console in async code
@mtreit I think I have something working now, thanks to your pointers. Found out I can lock on Console.Out directly, which made things far simpler. Apparently with the move to .NET Core this feature got originally removed in favor of private locking objects, but it was added back in due to the common use case of needing to change the console color in a thread-safe manner. I’m sure this could be more efficient, but it works for now at least.
using ProgressBar;
using System.Text;

ThreadSafeConsole.ReadLine();

Task task = Task.Run(async () =>
{
ConsoleProgressBar progressBar = new(100);

for (int i = 0; i < 100; i++)
{
progressBar.Increment();
await Task.Delay(50);
}
});

for (int i = 0; i <= 30; i++)
{
Thread.Sleep(100);
ThreadSafeConsole.WriteLine($"Message {i}");
}

await task;
Console.ReadKey();

namespace ProgressBar
{
internal static class ThreadSafeConsole
{
public static void Write(string message)
{
lock (Console.Out)
{
Console.Write(message);
}
}

public static void WriteLine(string message)
{
lock (Console.Out)
{
Console.WriteLine(message);
}
}

public static int Read()
{
int result;
lock (Console.Out)
{
result = Console.Read();
}
return result;
}

public static ConsoleKeyInfo ReadKey()
{
ConsoleKeyInfo result;
lock (Console.Out)
{
result = Console.ReadKey();
}
return result;
}

public static string? ReadLine()
{
string? result;
lock (Console.Out)
{
result = Console.ReadLine();
}
return result;
}
}

internal class ConsoleProgressBar(int total = 100)
{
private int? _progressBarCursorRow;
private int _current;

public void Increment(int value = 1)
{
lock (Console.Out)
{
bool isCursorVisible = Console.CursorVisible;
Console.CursorVisible = false;
_current += value;

if (_progressBarCursorRow == null)
{
_progressBarCursorRow = Console.CursorTop;
Console.WriteLine();
}

(int cursorLeft, int cursorTop) = Console.GetCursorPosition();
Console.SetCursorPosition(0, (int)_progressBarCursorRow);
Console.Write(new string(' ', Console.BufferWidth - 1));

Console.CursorLeft = 0;
Console.Write(this);
Console.SetCursorPosition(cursorLeft, cursorTop);

Console.CursorVisible = isCursorVisible;
}
}

public override string ToString()
{
StringBuilder stringBuilder = new();
stringBuilder.Append('[');

int percent = (int)(_current * 100 / total);
int p = (int)((percent / 10f) + .5f);

for (int i = 0; i < 10; ++i)
{
stringBuilder.Append(i >= p ? ' ' : '■');
}

stringBuilder.Append($"] {percent,3:##0}%");
return stringBuilder.ToString();
}
}
}
using ProgressBar;
using System.Text;

ThreadSafeConsole.ReadLine();

Task task = Task.Run(async () =>
{
ConsoleProgressBar progressBar = new(100);

for (int i = 0; i < 100; i++)
{
progressBar.Increment();
await Task.Delay(50);
}
});

for (int i = 0; i <= 30; i++)
{
Thread.Sleep(100);
ThreadSafeConsole.WriteLine($"Message {i}");
}

await task;
Console.ReadKey();

namespace ProgressBar
{
internal static class ThreadSafeConsole
{
public static void Write(string message)
{
lock (Console.Out)
{
Console.Write(message);
}
}

public static void WriteLine(string message)
{
lock (Console.Out)
{
Console.WriteLine(message);
}
}

public static int Read()
{
int result;
lock (Console.Out)
{
result = Console.Read();
}
return result;
}

public static ConsoleKeyInfo ReadKey()
{
ConsoleKeyInfo result;
lock (Console.Out)
{
result = Console.ReadKey();
}
return result;
}

public static string? ReadLine()
{
string? result;
lock (Console.Out)
{
result = Console.ReadLine();
}
return result;
}
}

internal class ConsoleProgressBar(int total = 100)
{
private int? _progressBarCursorRow;
private int _current;

public void Increment(int value = 1)
{
lock (Console.Out)
{
bool isCursorVisible = Console.CursorVisible;
Console.CursorVisible = false;
_current += value;

if (_progressBarCursorRow == null)
{
_progressBarCursorRow = Console.CursorTop;
Console.WriteLine();
}

(int cursorLeft, int cursorTop) = Console.GetCursorPosition();
Console.SetCursorPosition(0, (int)_progressBarCursorRow);
Console.Write(new string(' ', Console.BufferWidth - 1));

Console.CursorLeft = 0;
Console.Write(this);
Console.SetCursorPosition(cursorLeft, cursorTop);

Console.CursorVisible = isCursorVisible;
}
}

public override string ToString()
{
StringBuilder stringBuilder = new();
stringBuilder.Append('[');

int percent = (int)(_current * 100 / total);
int p = (int)((percent / 10f) + .5f);

for (int i = 0; i < 10; ++i)
{
stringBuilder.Append(i >= p ? ' ' : '■');
}

stringBuilder.Append($"] {percent,3:##0}%");
return stringBuilder.ToString();
}
}
}
16 replies
CC#
Created by Mayka on 2/12/2024 in #help
Properly locking the console in async code
@mtreit no it is not for learning purposes. i may no longer need it to be asynchronous now that I see I had the locking backwards… I’ll see what it ends up looking like when i rework this.
16 replies
CC#
Created by Mayka on 2/12/2024 in #help
Properly locking the console in async code
Thank you! That really clears things up. I’m quite new to async code in general, so sometimes I get things a bit jumbled up.
16 replies
CC#
Created by Mayka on 2/12/2024 in #help
Properly locking the console in async code
@mtreit ohhhhhhhh so I was thinking of it backwards, then. Thank you for the clarification! Sounds like perhaps I need to make a wrapper function for writing to the console that uses a semaphore slim and utilize that for any writing to console?
16 replies
CC#
Created by Mayka on 2/12/2024 in #help
Properly locking the console in async code
@mtreit I was trying to add a lock with this, maybe that’s not the correct way?
public async Task IncrementAsync(int? value = null)
{
await SemaphoreSlim.WaitAsync();

try
    {
    await Task.Run(() => IncrementProgressBar(value));
}
    finally
    {
    SemaphoreSlim.Release();
}
}
public async Task IncrementAsync(int? value = null)
{
await SemaphoreSlim.WaitAsync();

try
    {
    await Task.Run(() => IncrementProgressBar(value));
}
    finally
    {
    SemaphoreSlim.Release();
}
}
Trying to make it async so that I can have a progress bar that updates on a task running asynchronously while other things may be running and outputting to the console at the same time. Hence trying to make it just a bar at the bottom.
16 replies
CC#
Created by Mayka on 2/9/2024 in #help
ILogger Dependency Injection for Libraries
Do you have an example of what you mean? I am using the Msft.Ext.Logging ILogger interface in my example above already so that I’m not tied to Serilog. Is there a different area I would need to change as well?
75 replies
CC#
Created by PurplePeopleEater on 2/10/2024 in #help
Best logging library that supports working within "fire and forget" Task code
Haha whoops I’m gonna blame it on the time :catlaugh:
36 replies