nathanAjacobs
nathanAjacobs
CC#
Created by nathanAjacobs on 6/5/2024 in #help
NamedPipeClientStream.ReadAsync() continuously reads after the first message arrives
How come NamedPipeClientStream.ReadAsync continuously reads 0 bytes after the first message arrives? Basically is there a way to have it asynchronously wait until more data arrives after the first message?
5 replies
CC#
Created by nathanAjacobs on 5/6/2024 in #help
Can Memory<T> be created from a pointer?
Can Memory<T> be created with a pointer and a length? If not, how come?
15 replies
CC#
Created by nathanAjacobs on 2/27/2024 in #help
Help with LibraryImport and custom marshalling
What am I doing wrong here? I am getting a System.AccessViolationException when it tries to convert the first string (DeviceName) from unmanaged to managed.
[LibraryImport("user32.dll", EntryPoint = "EnumDisplayDevicesW", StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool EnumDisplayDevices(string? lpDevice, uint iDevNum, [MarshalUsing(typeof(DISPLAY_DEVICEMarshaller))] ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DISPLAY_DEVICE
{
[MarshalAs(UnmanagedType.U4)]
public uint cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string? DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string? DeviceString;
[MarshalAs(UnmanagedType.U4)]
public DisplayDeviceStateFlags StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string? DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string? DeviceKey;

public static DISPLAY_DEVICE Create() => new DISPLAY_DEVICE { cb = (uint)Marshal.SizeOf<DISPLAY_DEVICE>() };
}

[Flags]
public enum DisplayDeviceStateFlags : uint
{
AttachedToDesktop = 0x1,
MultiDriver = 0x2,
PrimaryDevice = 0x4,
MirroringDriver = 0x8,
VGACompatible = 0x10,
Removable = 0x20,
ModesPruned = 0x8000000,
Remote = 0x4000000,
Disconnect = 0x2000000
}

[CustomMarshaller(typeof(DISPLAY_DEVICE), MarshalMode.ManagedToUnmanagedRef, typeof(DISPLAY_DEVICEMarshaller))]
public static unsafe class DISPLAY_DEVICEMarshaller
{
internal struct DISPLAY_DEVICE_Unmanaged
{
public uint cb;
public ushort* DeviceName;
public ushort* DeviceString;
public uint StateFlags;
public ushort* DeviceID;
public ushort* DeviceKey;
}

public static DISPLAY_DEVICE ConvertToManaged(DISPLAY_DEVICE_Unmanaged unmanaged)
{
return new DISPLAY_DEVICE
{
cb = unmanaged.cb,
DeviceName = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceName),
DeviceString = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceString),
StateFlags = (DisplayDeviceStateFlags)unmanaged.StateFlags,
DeviceID = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceID),
DeviceKey = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceKey)
};
}

public static DISPLAY_DEVICE_Unmanaged ConvertToUnmanaged(DISPLAY_DEVICE managed)
{
return new DISPLAY_DEVICE_Unmanaged
{
cb = managed.cb,
DeviceName = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceName),
DeviceString = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceString),
StateFlags = (uint)managed.StateFlags,
DeviceID = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceID),
DeviceKey = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceKey)
};
}

public static unsafe void Free(DISPLAY_DEVICE_Unmanaged unmanaged)
{
Utf16StringMarshaller.Free(unmanaged.DeviceName);
Utf16StringMarshaller.Free(unmanaged.DeviceString);
Utf16StringMarshaller.Free(unmanaged.DeviceID);
Utf16StringMarshaller.Free(unmanaged.DeviceKey);
}
}
[LibraryImport("user32.dll", EntryPoint = "EnumDisplayDevicesW", StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool EnumDisplayDevices(string? lpDevice, uint iDevNum, [MarshalUsing(typeof(DISPLAY_DEVICEMarshaller))] ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DISPLAY_DEVICE
{
[MarshalAs(UnmanagedType.U4)]
public uint cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string? DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string? DeviceString;
[MarshalAs(UnmanagedType.U4)]
public DisplayDeviceStateFlags StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string? DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string? DeviceKey;

public static DISPLAY_DEVICE Create() => new DISPLAY_DEVICE { cb = (uint)Marshal.SizeOf<DISPLAY_DEVICE>() };
}

[Flags]
public enum DisplayDeviceStateFlags : uint
{
AttachedToDesktop = 0x1,
MultiDriver = 0x2,
PrimaryDevice = 0x4,
MirroringDriver = 0x8,
VGACompatible = 0x10,
Removable = 0x20,
ModesPruned = 0x8000000,
Remote = 0x4000000,
Disconnect = 0x2000000
}

[CustomMarshaller(typeof(DISPLAY_DEVICE), MarshalMode.ManagedToUnmanagedRef, typeof(DISPLAY_DEVICEMarshaller))]
public static unsafe class DISPLAY_DEVICEMarshaller
{
internal struct DISPLAY_DEVICE_Unmanaged
{
public uint cb;
public ushort* DeviceName;
public ushort* DeviceString;
public uint StateFlags;
public ushort* DeviceID;
public ushort* DeviceKey;
}

public static DISPLAY_DEVICE ConvertToManaged(DISPLAY_DEVICE_Unmanaged unmanaged)
{
return new DISPLAY_DEVICE
{
cb = unmanaged.cb,
DeviceName = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceName),
DeviceString = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceString),
StateFlags = (DisplayDeviceStateFlags)unmanaged.StateFlags,
DeviceID = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceID),
DeviceKey = Utf16StringMarshaller.ConvertToManaged(unmanaged.DeviceKey)
};
}

public static DISPLAY_DEVICE_Unmanaged ConvertToUnmanaged(DISPLAY_DEVICE managed)
{
return new DISPLAY_DEVICE_Unmanaged
{
cb = managed.cb,
DeviceName = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceName),
DeviceString = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceString),
StateFlags = (uint)managed.StateFlags,
DeviceID = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceID),
DeviceKey = Utf16StringMarshaller.ConvertToUnmanaged(managed.DeviceKey)
};
}

public static unsafe void Free(DISPLAY_DEVICE_Unmanaged unmanaged)
{
Utf16StringMarshaller.Free(unmanaged.DeviceName);
Utf16StringMarshaller.Free(unmanaged.DeviceString);
Utf16StringMarshaller.Free(unmanaged.DeviceID);
Utf16StringMarshaller.Free(unmanaged.DeviceKey);
}
}
Calling code:
public static DISPLAY_DEVICE GetPrimaryDisplay()
{
uint id = 0;
while (true)
{
DISPLAY_DEVICE d = DISPLAY_DEVICE.Create();

bool done = EnumDisplayDevices(null, id, ref d, 0);

if ((d.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) == DisplayDeviceStateFlags.PrimaryDevice)
{
return d;
}

if (done)
break;

id++;
}

return default;
}
public static DISPLAY_DEVICE GetPrimaryDisplay()
{
uint id = 0;
while (true)
{
DISPLAY_DEVICE d = DISPLAY_DEVICE.Create();

bool done = EnumDisplayDevices(null, id, ref d, 0);

if ((d.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) == DisplayDeviceStateFlags.PrimaryDevice)
{
return d;
}

if (done)
break;

id++;
}

return default;
}
15 replies
CC#
Created by nathanAjacobs on 2/7/2024 in #help
What exactly do these limitations mean for NativeAOT?
24 replies
CC#
Created by nathanAjacobs on 1/19/2024 in #help
Optional parameters with dependency injection
Is it possible to have an optional parameter for a constructor with dependency injection. I know that dependency injection usually it implies it is a required dependency, but for example if the only dependency is an ILogger, then I don't really care if one was registered or not. EDIT: Changed ILogger<Test> to be nullable
public class Test
{
private readonly ILogger<Test>? _logger;

public Test(ILogger<Test>? logger = null) // does this work?
{
_logger = logger
}

public void DoSomething()
{
_logger?.LogInformation("Doing something...");
}
}
public class Test
{
private readonly ILogger<Test>? _logger;

public Test(ILogger<Test>? logger = null) // does this work?
{
_logger = logger
}

public void DoSomething()
{
_logger?.LogInformation("Doing something...");
}
}
10 replies
CC#
Created by nathanAjacobs on 12/27/2023 in #help
Is there any difference between named arguments and default constructor arguments for an attribute?
Is there any difference between these attributes? Is one better to use than the other?
[AttributeUsage(AttributeTargets.Class)]
public class CustomAttribute : System.Attribute
{
public string Name { get; }

public CustomAttribute(string name = "")
{
Name = name;
}
}

[AttributeUsage(AttributeTargets.Class)]
public class CustomNonDefaultAttribute : System.Attribute
{
public string Name { get; set; } = "";
}

[Custom(name: "sdfsd")]
[CustomNonDefault(Name = "sdfsd")]
public class MyClass
{
}
[AttributeUsage(AttributeTargets.Class)]
public class CustomAttribute : System.Attribute
{
public string Name { get; }

public CustomAttribute(string name = "")
{
Name = name;
}
}

[AttributeUsage(AttributeTargets.Class)]
public class CustomNonDefaultAttribute : System.Attribute
{
public string Name { get; set; } = "";
}

[Custom(name: "sdfsd")]
[CustomNonDefault(Name = "sdfsd")]
public class MyClass
{
}
3 replies
CC#
Created by nathanAjacobs on 10/9/2023 in #help
❔ Are there read only collections that don't box enumerators?
ReadOnlyCollection<T> boxes struct enumerators since it stores IList<T> internally. ImmutableList<T> does not box enumerator, but I actually want to publically expose a List as read only and privately be able to modify it.
11 replies
CC#
Created by nathanAjacobs on 7/17/2023 in #help
✅ Would a ConcurrentDictionary be necessary if I am only adding and never removing?
Would a ConcurrentDictionary be necessary if I'm only ever adding keys and never removing them? Also I'm not using the values of the dictionary so if ConcurrentDictionary is not needed I could use a regular HashSet instead.
12 replies
CC#
Created by nathanAjacobs on 12/27/2022 in #help
❔ WindowsAppSDK (WinUI 3) shutdown app before window is shown?
In WindowsAppSDK (WinUI 3) is it possible to shutdown the application specifically in the OnLaunched override before the main window is shown? Application.Exit() does not work until the main window is shown.
2 replies
CC#
Created by nathanAjacobs on 12/24/2022 in #help
❔ Did Visual Studio change how async exceptions break?
If I am remembering correctly, Visual Studio used to break on the await of the Task when an exception occurred in the Task. However Visual Studio is now breaking inside the Task method. Has this behavior changed?
static async Task Main(string[] args)
{
await TestAsync(); // shouldn't break happen here?
}

static async Task TestAsync()
{
await Task.Delay(1000);
throw new Exception(); // break occurs here
}
static async Task Main(string[] args)
{
await TestAsync(); // shouldn't break happen here?
}

static async Task TestAsync()
{
await Task.Delay(1000);
throw new Exception(); // break occurs here
}
3 replies
CC#
Created by nathanAjacobs on 12/13/2022 in #help
❔ Is it possible to have WPF window hidden until Blazor WebView loads page?
I'm trying to hide a WPF window until the Blazor WebView loads, but it seems that the initialization of the webview does not happen until the window is actually shown. Is there a way to do this?
2 replies
CC#
Created by nathanAjacobs on 10/13/2022 in #help
Why are out parameters inside an if statement condition not local to the if block? [Answered]
if (dictionary.TryGetValue(key, out var val))
{

}

// why can I access val here?
if (dictionary.TryGetValue(key, out var val))
{

}

// why can I access val here?
Is this because of how it ends up compiling val above the if statement?
10 replies
CC#
Created by nathanAjacobs on 9/13/2022 in #help
Processing incoming networking messages
Say I have a processing loop which processes incoming network messages asynchronously with ConfigureAwait(false). Should I synchronize back to the SynchronizationContext (if there is one) to invoke the callback delegates that are subscribed to the message type?
12 replies
CC#
Created by nathanAjacobs on 9/4/2022 in #help
Stream.DisposeAsync() .NET Standard 2.0 [Answered]
Is there any way to dispose a stream asynchronously in .NET Standard 2.0? Would using await Task.Run(stream.Dispose); work?
6 replies