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
Decrypting a byte array in memory is not something where async makes sense...if you decrypt it synchronously does it work?
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.
Is this on the UI thread or something?
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.
I see. Your program crashes?
Well, it just gets blocked if I do it sync; async it crashed without error.
"A crash without any error" doesn't really sound correct
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
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.
Right. I may have multiple of these to either run in sequence or parallel; how would I best implement this ?
I never write UI code and know nothing about Unity so not sure what all of the obstacles are
Is this on Windows?
Yes
Anything in the Application event log?
Not sure I have one from the app itself; this is on Mono (using that for debugging, later targeting IL2CPP. No CoreCLR :/)
I mean the Windows Event Log
eventvwr
Oh
.NET and/or the OS might log something there
If something fatal is happening
Doesn’t seem like it.
Ok
You might see if someone in #game-dev knows about Unity / async weirdness
I can try I guess
Use $paste
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!
Oh alright
BlazeBin - nunolfqowwhs
A tool for sharing your source code with the world!
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.
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 threadsHow can I avoid that occurring ?
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
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 ?
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
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.