C
C#2y ago
Nolram

Async operations cause errorless crash (Task.Run etc.)

I am currently attempting to load about ~190MB worth of byte data from a file and decrypt it asynchronously. Loading the data using byte[] fileBytes = File.ReadAllBytes(...).ConfigureAwait(false) seems to work just fine - however, attempting to run the AES decryption on it with byte[] decryptedBytes = await Task.Run(() => DecryptionFunction(...))).ConfigureAwait(false); causes a crash without any error - not with a managed debugger (Rider) or Native Debugger (VS) or in the log files Unity provides.
32 Replies
mtreit
mtreit2y ago
Decrypting a byte array in memory is not something where async makes sense...if you decrypt it synchronously does it work?
Nolram
Nolram2y ago
Yes. But it takes a good 10 seconds or so, so I would like to do it async. Or at least be non-blocking in some capacity. I could also use a faster encryption algorithm if one is available; or a “pseudo-encryption” algorithm, security is not too important here.
mtreit
mtreit2y ago
Is this on the UI thread or something?
Nolram
Nolram2y ago
All of that is running in a static async function that is being called from the main thread, yes So if it runs synchronously it blocks.
mtreit
mtreit2y ago
I see. Your program crashes?
Nolram
Nolram2y ago
Well, it just gets blocked if I do it sync; async it crashed without error.
mtreit
mtreit2y ago
"A crash without any error" doesn't really sound correct
Nolram
Nolram2y ago
I know, it confusing to me as well; potentially some Unity weirdness. But I checked both with a managed debugger, native debugger and everything - but it just... exits. I have a series of functions and data processing operations I need to run here; so I am unsure how to best structure everything to run as async as possible so the main thread does not get blocked Data flow is as following : Load file > Decrypt > (Optionally) Decompress (LZMA) > Register data with Unity
mtreit
mtreit2y ago
You could just run the task in parallel and have it signal when it's done via a callback or setting some flag and have your main loop check that. Or even just poll the task status.
Nolram
Nolram2y ago
Right. I may have multiple of these to either run in sequence or parallel; how would I best implement this ?
mtreit
mtreit2y ago
I never write UI code and know nothing about Unity so not sure what all of the obstacles are Is this on Windows?
Nolram
Nolram2y ago
Yes
mtreit
mtreit2y ago
Anything in the Application event log?
Nolram
Nolram2y ago
Not sure I have one from the app itself; this is on Mono (using that for debugging, later targeting IL2CPP. No CoreCLR :/)
mtreit
mtreit2y ago
I mean the Windows Event Log eventvwr
Nolram
Nolram2y ago
Oh
mtreit
mtreit2y ago
.NET and/or the OS might log something there If something fatal is happening
Nolram
Nolram2y ago
Doesn’t seem like it.
mtreit
mtreit2y ago
Ok You might see if someone in #game-dev knows about Unity / async weirdness
Nolram
Nolram2y ago
I can try I guess
Nolram
Nolram2y ago
This is the mess of code I have created in the last 5 days attempting to get this to work in any way, shape or form :
mtreit
mtreit2y ago
Use $paste
MODiX
MODiX2y ago
If your code is too long, you can post to https://paste.mod.gg/ and copy the link into chat for others to see your shared code!
Nolram
Nolram2y ago
Oh alright
Nolram
Nolram2y ago
BlazeBin - nunolfqowwhs
A tool for sharing your source code with the world!
Nolram
Nolram2y ago
Thats the function causing the error in my case. Everything up to it works just fine. All data is passed in correctly. A lot of it is garbo debugging code and commented-out stuff Crash happens on line 15.
atakancracker
atakancracker2y ago
Async void methods have different error-handling semantics. When an exception is thrown out of an async Task or async Task<T> method, that exception is captured and placed on the Task object. With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started. Figure 2 illustrates that exceptions thrown from async void methods can’t be caught naturally. https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming consider using async Task rather than async void In your case, "crash without error" and as I see you use "async void", this subject fits for your case there you use async Task so it looks good but you are calling Task.Run inside a loop. You might run out of threads
Nolram
Nolram2y ago
How can I avoid that occurring ?
atakancracker
atakancracker2y ago
any reason to use Task.Run ? you have lots of ConfigureAwait(false) which will consume new threads for each iterations using ConfigureAwait(false) for File.ReadAllBytesAsync this method makes sense but the other methods should not be necessary using all of the available threads in order to increase speed can cause such problems, its better to stick with async await way if not particularly necessary
Nolram
Nolram2y ago
Well, I have various functions that aren’t natively async that I need to run. On the others it crashes with or without Yeah, as long as it does not block I dont care too much, I am just not sure how to get everything to behave properly in an async context. Any further ideas ?
atakancracker
atakancracker2y ago
Not really, you can try to get dump from windows to diagnose If you have not awaited async methods the request pipeline will continue to end without waiting response or any error, thats one case often I face with Maybe you can try to debug that code outside of unity environment And you can use some logging to see in where exactly you are having problem and you can log the states There you find the function causing the problem right ? Next step you can find which line is breaking and up to which line you are succeed you can diagnose with logging. (you can create File.WriteAllText create txt file to custom logging shortest way) Those what comes my mind
Nolram
Nolram2y ago
Well, thats what I do - these are issues that occur at runtime. Yeah. The function causing problems is the decryption Task.Run, which causes a crash. Synchronously it does not.