HimmDawg
HimmDawg
Explore posts from servers
CC#
Created by HimmDawg on 2/8/2023 in #help
❔ Sudden OutOfMemoryException due to OS change?
Let's imagine a WinForms .NET Framework 4.8 app is running on Win10 just fine, but under Win11 it suddenly causes OutOfMemoryExceptions due to exceeding the handle limit. Do you guys have a clue what could be the problem? fluffyFoxThink
28 replies
CC#
Created by HimmDawg on 12/19/2022 in #help
❔ Deadlock with SynchonizationContext and locks?
I have quite a tricky problem fluffyFoxThink Our WinForms .NET Framework 4.8 program has a UI thread and a System.Timers.Timer. In the Elapsed event, I do some stuff that is dispatched to the UI thread via SynchronizationContext.Post(). https://paste.mod.gg/sbclvarnxuwv/0 PushNotification is a function that takes a NotificationPopup (simply a Form with some extras) and pushes it to a queue, which dequeues those Forms and shows them on screen. Just like a popup. If I don't use that Post() then the Forms have holes where the controls should be. https://paste.mod.gg/sbclvarnxuwv/1 Now the thing is, on other pcs, this can lead to an exception where the thread the context is from does no longer exist. A coworker inserted some locks, which didn't really help and I don't see any obvious problem. What I did so far was instead of getting the context inside of this class itself, I got it on the ui thread and injected it into the constructor. I know the code samples are a bit over the place, but this thing is quite massive, so if something is unclear, then I'll provide some mode code
14 replies
CC#
Created by HimmDawg on 12/14/2022 in #help
❔ Process.Exited immediately fired if corresponding app is already opened
I wrote a function that downloads a PDF from some API and then attempts to open it. For this reason, I save the pdf in a tmp file and then use Process to open the default app for it - in this case Adobe Acrobat Reader. The code looks like this
string tmpFilePath = File.Exists($"{Path.GetTempPath()}{pdfFile}")
? $"{Path.GetTempPath()}{Environment.TickCount}_{pdfFile}"
: $"{Path.GetTempPath()}{pdfFile}";

Process p = new Process();
p.StartInfo.FileName = tmpFilePath;
p.EnableRaisingEvents = true;
p.Exited += (s, e) =>
{
p.WaitForExit();
if (File.Exists(tmpFilePath))
{
File.Delete(tmpFilePath);
p.Close();
}
};
p.Start();
string tmpFilePath = File.Exists($"{Path.GetTempPath()}{pdfFile}")
? $"{Path.GetTempPath()}{Environment.TickCount}_{pdfFile}"
: $"{Path.GetTempPath()}{pdfFile}";

Process p = new Process();
p.StartInfo.FileName = tmpFilePath;
p.EnableRaisingEvents = true;
p.Exited += (s, e) =>
{
p.WaitForExit();
if (File.Exists(tmpFilePath))
{
File.Delete(tmpFilePath);
p.Close();
}
};
p.Start();
The problem occures when Acrobat Reader is opened before I download the PDF. For some reason, the Exited event is immediately fired when I try to open the file. But then I get an error on the line File.Delete saying that the file is already in use (presumably by the acrobat reader). Not sure what the "best practice" is to handle Process the right way here fluffyFoxThink
3 replies
CC#
Created by HimmDawg on 12/12/2022 in #help
Generic api base client
I'm trying to implement a generic api base client using Polly and System.Net.Http.Formatting. I have this GetAsync<T>(string url) function here
public async Task<RestResponse<T>> GetAsync<T>(string url)
{
var response = await _retryPolicy.ExecuteAsync(async () => await _httpClient.GetAsync(url));

if (!response.IsSuccessStatusCode)
{
throw new Exception($"Failed to call API endpoint. Status code: {response.StatusCode}");
}

//var content = await response.Content.ReadAsByteArrayAsync();
var content2 = await response.Content.ReadAsAsync<T>();
return new RestResponse<T>(response.StatusCode, content2);
}
public async Task<RestResponse<T>> GetAsync<T>(string url)
{
var response = await _retryPolicy.ExecuteAsync(async () => await _httpClient.GetAsync(url));

if (!response.IsSuccessStatusCode)
{
throw new Exception($"Failed to call API endpoint. Status code: {response.StatusCode}");
}

//var content = await response.Content.ReadAsByteArrayAsync();
var content2 = await response.Content.ReadAsAsync<T>();
return new RestResponse<T>(response.StatusCode, content2);
}
RestResponse just encapsulates the data and the statuscode and _retryPolicy is an IAsyncPolicy from Polly.
public class RestResponse<T>
{
public RestResponse(HttpStatusCode statusCode, T data)
{
StatusCode = statusCode;
Data = data;
}

public HttpStatusCode StatusCode { get; set; }

public T Data { get; set; }
}
public class RestResponse<T>
{
public RestResponse(HttpStatusCode statusCode, T data)
{
StatusCode = statusCode;
Data = data;
}

public HttpStatusCode StatusCode { get; set; }

public T Data { get; set; }
}
Now the question is: Could I somehow use this function when T is byte[]? If I do that in the current state, then I get an error, that the media type of the response data is application/pdf and no MediaTypeFormatter exists for that.
2 replies
CC#
Created by HimmDawg on 11/29/2022 in #help
❔ PostgreSQL DateTime in EF Core
43 replies
CC#
Created by HimmDawg on 11/21/2022 in #help
Mocking FileStream for integration testing
I made a simple integration test that tests some functionality after calling an API endpoint. In my api client, I have this function UploadDocumentAsync(string filePath)
public async Task<RestResponse<int>> UploadDocumentAsync(string filePath)
{
using var formData = new MultipartFormDataContent();

var fileStream = new StreamContent(new FileStream(filePath));
var fileName = Path.GetFileName(filePath);

// ...
}
public async Task<RestResponse<int>> UploadDocumentAsync(string filePath)
{
using var formData = new MultipartFormDataContent();

var fileStream = new StreamContent(new FileStream(filePath));
var fileName = Path.GetFileName(filePath);

// ...
}
As you can see, this function expects a string as an argument. To make the function testable though, I'd need an abstraction for FileStream (which I know exists as a NuGet package) and inject it into the function. The question is: Is that better? I know it doesn't sound too bad, but calling the function with a FileStream instead of a string takes away a bit of comfort imo. I don't know if that's just silly goblinresHide . Or maybe you guys know another way to test such a function
8 replies
CC#
Created by HimmDawg on 9/12/2022 in #help
Replacing font table in RichTextBox (WinForms)
I'm working on a .NET Framework 4.8 app that uses WinForms and in there, RichTextBox is used. The app has a list of supported fonts, so we made an algorithm that sorts out unknown fonts when you type or paste text with fonts that are not on the list. If an unknown font ist detected every character having an unknown font will be set to a default font from that list. Now, somebody copied a text from a pdf and pasted it into a richtext box. The fonts in the table are Times New Roman, TimesNewRoman, TimesNewRoman,Bold. So the algorithm (correctly) detects TimesNewRoman, TimesNewRoman,Bold as unknown and tries to replace those. But in reality, it didn't do anything because the text didn't contain characters with one of those two fonts, thus leaving the two unknown fonts in the fonttable. I collected the fonts actually contained in the text with
IEnumerable<string> actualFonts = new List<string>();

for (int i = 0; i < riText.TextLength; i++)
{
riText.Select(i, 1);
actualFonts.Add(riText.SelectionFont.FontFamily.Name);
}
IEnumerable<string> actualFonts = new List<string>();

for (int i = 0; i < riText.TextLength; i++)
{
riText.Select(i, 1);
actualFonts.Add(riText.SelectionFont.FontFamily.Name);
}
...and in there, I got 3x Microsoft Sans Serif (different font sizes) and 2x Times New Roman (different font sizes). I'm a bit lost here. Manually replacing the fonttable doesn't work. What can I do?
2 replies
CC#
Created by HimmDawg on 9/5/2022 in #help
WinUI3 app doesn't run outside of Visual Studio
I just tried to share a tool I made in WinUI3 with .NET6. That shouldn't be a problem with the publish feature in Visual Studio, right? Well, for some reason winui apps wont run in any configuration at all after publishing them to a folder. So then I built my application in release mode again and grabbed the generated files. I thought this would run no problem, but it wouldn't. Same goes for files in debug mode. I must be missing a key information here...
5 replies
CC#
Created by HimmDawg on 8/30/2022 in #help
HttpClient.GetStringAsync() is slow
Hey owo I wanted to download some gifs from a wiki page via a console app. Everything works and all, but when it comes to downloading the images, it's kinda slow. So here's the crucial part
for (int i = 0; i < names.Count(); i++)
{
Console.Write($"Download gif ({progress} / {names.Count()})");

string name = names[i];

var pageSourceCode = await client.GetStringAsync($"{baseURL}/{name}_idle_animation.gif");
Regex gifFinderRegex = new Regex(@"<a href=""(/images/[a-zA-Z0-9]/[a-zA-Z0-9]{2}/[a-zA-Z0-9]+_idle_animation\.gif)"">");

Match match = gifFinderRegex.Match(pageSourceCode);

byte[] fileBytes = await client.GetByteArrayAsync($"{baseURL}{match.Groups[1]}");
File.WriteAllBytes(Path.Combine(saveLocation, name + ".gif"), fileBytes);

progress++;
Console.Write("\r");
}
for (int i = 0; i < names.Count(); i++)
{
Console.Write($"Download gif ({progress} / {names.Count()})");

string name = names[i];

var pageSourceCode = await client.GetStringAsync($"{baseURL}/{name}_idle_animation.gif");
Regex gifFinderRegex = new Regex(@"<a href=""(/images/[a-zA-Z0-9]/[a-zA-Z0-9]{2}/[a-zA-Z0-9]+_idle_animation\.gif)"">");

Match match = gifFinderRegex.Match(pageSourceCode);

byte[] fileBytes = await client.GetByteArrayAsync($"{baseURL}{match.Groups[1]}");
File.WriteAllBytes(Path.Combine(saveLocation, name + ".gif"), fileBytes);

progress++;
Console.Write("\r");
}
Granted, I'm doing some really slow things here like two requests, I/O and Regex on a huge string, but assuming the server is 100% responsive, it shouldn't take 10s for one iteration. Not sure what's happening in the background foxThinking
16 replies
CC#
Created by HimmDawg on 8/16/2022 in #help
Using async,await in old codebase
Currently, I'm implementing a custom control that utilizes an API, so there are some async methods. The problem is that I cannot wrap my head around, how I would use them in this old codebase I'm working on (WinForms, .NET Framework 4.8). Simplified example: The user control has this method
public async Task LoadDocuments(int id)
{
// ...
}
public async Task LoadDocuments(int id)
{
// ...
}
I'd need to integrate it here somehow
void Init()
{
/*await*/ this.customControl.LoadDocuments(this.id);
}
void Init()
{
/*await*/ this.customControl.LoadDocuments(this.id);
}
Here I could change void to Task and put an async in front of it. That'd work, but this method is used here...
protected override void Method1()
{
/*await*/ Init();
}

protected override bool Method2()
{
/*await*/ Init();
}
protected override void Method1()
{
/*await*/ Init();
}

protected override bool Method2()
{
/*await*/ Init();
}
(don't ask about method names and how much they do not make sense) In the first method, i could theoretically use async and leave void as is, but in the second case, i cannot easily add async to the method, because now it requires a Task<bool> of course. Anybody got an idea?
7 replies