|
Mr Shiny Pants posted:Is it safe to use recursive functions within AspNetCore? I've never worked with websockets, but: https://docs.microsoft.com/it-it/aspnet/core/fundamentals/websockets?view=aspnetcore-3.0 quote:When using a WebSocket, you must keep the middleware pipeline running for the duration of the connection. If you attempt to send or receive a WebSocket message after the middleware pipeline ends, you may get an exception like the following: quote:When accepting the WebSocket connection before beginning the loop, the middleware pipeline ends. Upon closing the socket, the pipeline unwinds. That is, the request stops moving forward in the pipeline when the WebSocket is accepted. When the loop is finished and the socket is closed, the request proceeds back up the pipeline. That really sounds to me like you're supposed to lock down that pipeline as long as the websocket is active, and it makes intuitive sense as well - it's an ongoing connection, if you were dropping the pipeline and being stateless you'd just be doing HTTP. NihilCredo fucked around with this message at 17:16 on Oct 3, 2019 |
# ? Oct 3, 2019 17:11 |
|
|
# ? Jun 7, 2024 16:36 |
|
NihilCredo posted:I've never worked with websockets, but: Yes, that was also what I stumbled upon and how it works right now, I was just wondering if making it recursive within a framework would blow up. Tail call optimisation and the like. Mr Shiny Pants fucked around with this message at 17:20 on Oct 3, 2019 |
# ? Oct 3, 2019 17:14 |
|
Mr Shiny Pants posted:Yes, that was also what I stumbled upon and how it works right now, I was just wondering if making it recursive within a framework would blow up. Tail recursion and the like. Ahh. I think tail call optimizations happen at a much lower level, so you should be able to just open up the .dll with an IL analyzer and see either (a) the loop version of the function (created by the compiler) or (b) the tail. IL command. Or you can just run your loop a few dozen times in release mode, then log an exception and check the call stack size. Incidentally, can you post your Giraffe pipeline? I have to deal with the lovely MS controller architecture because I need OpenAPI autogeneration, but I've always wanted to switch to Giraffe because that composition root looks gorgeous.
|
# ? Oct 3, 2019 17:22 |
|
NihilCredo posted:Ahh. I think tail call optimizations happen at a much lower level, so you should be able to just open up the .dll with an IL analyzer and see either (a) the loop version of the function (created by the compiler) or (b) the tail. IL command. Hmmm that's quite the thing..... I'll try and figure out how that's working. Thanks. Giraffe is really nice for normal HTTP stuff, the websocket logic does not really work with the >=> ( kleisli?) combinators. Documentation is a bit sparse, so maybe I am just not understanding it correctly. I have it at work, I'll post it when I am back at my desk.
|
# ? Oct 3, 2019 17:29 |
|
NihilCredo posted:Ahh. I think tail call optimizations happen at a much lower level, so you should be able to just open up the .dll with an IL analyzer and see either (a) the loop version of the function (created by the compiler) or (b) the tail. IL command. Correct me if I'm wrong, but for some esoteric reason C# does not do tail call recursion. Any recursive function can overflow.
|
# ? Oct 3, 2019 18:14 |
|
Cuntpunch posted:Correct me if I'm wrong, but for some esoteric reason C# does not do tail call recursion. Any recursive function can overflow. Correct. Further discussion here: https://github.com/dotnet/csharplang/issues/2544
|
# ? Oct 3, 2019 18:31 |
|
Cuntpunch posted:Correct me if I'm wrong, but for some esoteric reason C# does not do tail call recursion. quote:Thanks for the suggestion. We've considered emiting tail call instructions at a number of points in the development of the C# compiler. However, there are some subtle issues which have pushed us to avoid this so far: That was 2007, but it still seems to be the case: https://github.com/dotnet/csharplang/issues/2544 e;f,b.
|
# ? Oct 3, 2019 18:32 |
|
Cuntpunch posted:Correct me if I'm wrong, but for some esoteric reason C# does not do tail call recursion. Any recursive function can overflow. He's writing F#.
|
# ? Oct 3, 2019 22:30 |
|
Did Office 2019 Excel files get a new OLEDB connection string, by some esoteric chance? I've got perfectly good .xlsx files that aren't corrupted or anything -- they'll open in Excel -- but both Microsoft.ACE.OLEDB.12.0 and Microsoft.Jet.OLEDB.4.0 (I tried it just in case) are giving me the same Not In Expected Format errors. The same code will process other Excel files just fine and the department generating the ones that are failing have no idea what version of Excel they use or what could possibly be different about them, and I can't find any other connection strings on Google, but I'm utterly out of ideas and Not In Expected Format gives me dick-all to go off of.
|
# ? Oct 4, 2019 00:31 |
|
CapnAndy posted:Did Office 2019 Excel files get a new OLEDB connection string, by some esoteric chance? I've got perfectly good .xlsx files that aren't corrupted or anything -- they'll open in Excel -- but both Microsoft.ACE.OLEDB.12.0 and Microsoft.Jet.OLEDB.4.0 (I tried it just in case) are giving me the same Not In Expected Format errors. The same code will process other Excel files just fine and the department generating the ones that are failing have no idea what version of Excel they use or what could possibly be different about them, and I can't find any other connection strings on Google, but I'm utterly out of ideas and Not In Expected Format gives me dick-all to go off of. mystes fucked around with this message at 01:35 on Oct 4, 2019 |
# ? Oct 4, 2019 01:32 |
|
Does anybody know of a way to capture warning and errors from the output of dotnet build, other than manual regexes? (Use case: in our CI system, I want to allow builds with warnings to be deployed to test, but prevent them from being deployed to production. I could just re-build with warnings-as-errors, but it would double CI times.) EDIT: Found it, dotnet build can't do it but dotnet msbuild can use all the fancy stuff: code:
NihilCredo fucked around with this message at 21:16 on Oct 4, 2019 |
# ? Oct 4, 2019 21:03 |
|
I've scratched the websocket stuff, If you are still interested I can post the code. I was working on something distributed that needs to keep all connected devices updated in semi realtime, after going through all the stuff needed for this, without going all in on SignalR, I've decided that it may be smarter to use Kafka and have all the clients connected to a specific topic over websockets. Especially because it keeps track of where everyone is in reading the messages.
|
# ? Oct 5, 2019 08:33 |
|
I'm working on some Azure data related tasks and struggling to do something that I think should be a pretty standard operation. I need to be able to open up a blob from a blob triggered function as a stream that's going to be a large CSV file and chunk it into some arbitrary number of gziped files between 10-100mb each (compressed). I understand how to open up a blob and stream the data to another blob as a single compressed file but I'm getting kind of lost figuring out how to #1 create gzip files that fall within a designated size limit after compression and #2 how to break up the stream into multiple smaller files. For reference I'm using the basic Azure function template that provides the source blob as a Stream and I'm attempting to use GZipStream with a block blob passed in as the reference. Can a single block blob be multiple files?
|
# ? Oct 10, 2019 01:10 |
|
I have no relevant experience, but I think the only way to know how large a compressed stream of data will be is to run the compression algorithm. Unless your source CSV is particularly pathological, your compression ratio is (I'm guessing) going to be around 5-10%, so maybe just chunk 500MB of uncompressed data at a time, and the compressed files will usually be 25-50MB. And then I think you're done, because it looks like it's relatively straightforward to take a bunch of smaller .gz files and get uncompressed output that is the same as concatenating the original uncompressed output.
|
# ? Oct 10, 2019 17:28 |
|
I'm experimenting with migrating some code using a lot of IEnumerables as coroutines to using async-await. I have stubbed my toe in a few places: 1. I don't have the rig in front of me but I want to say it's running VS2018, and it really sucks at taking me to the site of an exception when something screws up in a Task. Is this something that has improved, or is there some manner in which I can improve getting the right call stack? I seem to get stranded in mscorlib with the exception message and I just kind of have to infer. This has be far been the most frustrating part of the whole thing. 2. What are people's thoughts on using var for automatic static type deduction when adapting code like this? I had a really nasty problem where I had some code waiting for a Task<object> and wound up somehow getting a Task<Task<object>>. I'm not sure if I can really tighten up the generic parameter any further since it's a wrapper for basically any kind of embedded call with any kind of return signature. I don't think typing it explicitly as Task<object> would have worked because Task<object> is also an object and just fine. But I'd love to get slapped on the wrist more for this at compile-time. 3. Has anybody had any luck trying to write a little scheduler for managing various things that may or may not block? I have one with a loop but it really was spinning on itself. With IEnumerables that didn't actually block in unit tests, I could assert that it should only loop once. With async-await, I was seeing over 2500 iterations for the same cases. I'd like to use some kind of tick count as a canary for particularly-bad coroutines, but not if I can normally expect a lot of looping around like this. Update: It looks like I was actually using VS2017. I'm messing around with VS2019 and getting different effects in the debugger. Currently, if I debug a unit test, it'll take me to the right spot, but I have to try some more to ensure I'm getting into exposure into Tasks that are acting up. Rocko Bonaparte fucked around with this message at 05:53 on Oct 11, 2019 |
# ? Oct 10, 2019 22:47 |
|
Rocko Bonaparte posted:I'm experimenting with migrating some code using a lot of IEnumerables as coroutines to using async-await. I have stubbed my toe in a few places: A Task<Task<object>> is not actually a Task<object> - by all means stop using var if it will help avoid bugs.
|
# ? Oct 14, 2019 03:45 |
|
I've seen async/await focused Roslyn code analyzers out there that will yell at you if you downcast Task<T> to Task, Task, to void, and other stuff like that.
|
# ? Oct 14, 2019 04:25 |
|
rarbatrol posted:I've seen async/await focused Roslyn code analyzers out there that will yell at you if you downcast Task<T> to Task, Task, to void, and other stuff like that. Some of them also do stupid poo poo like demand that you remove "unnecessary" async despite the semantics of C# code:
C# code:
Another stupid one is demanding ConfigureAwait on all awaits even if the thing being awaited doesn't actually have a ConfigureAwait method.
|
# ? Oct 14, 2019 04:35 |
|
raminasi posted:Some of them also do stupid poo poo like demand that you remove "unnecessary" async despite the semantics of I think the idea of that suggestion is that you should really make sure that's what you want to be doing. Like, is there a reason you're using await, maybe just return the task so the caller can decide.
|
# ? Oct 14, 2019 04:59 |
|
I was able to convert all those IEnumerable coroutines I had written to use async-await. It got rid of a boilerplate I had to use all over the place, but the current code is powered by voodoo. I had tried to set this up so that my coroutines were managed by its own scheduler so I can throttle them back and I have ... mostly succeeded. I think I have completely succeeded but I'm still trying to figure out why the scheduler ends up ticking through the scheduler loop more than once. However, it not longer ticks through the scheduler 2,000+ times. It's usually just twice, but I was trying to make it just once--and consistently once--for the sake of asserting good behavior. Anyways, what I really don't understand is why I might deadlock if I have a sequence like this: code:
code:
|
# ? Oct 15, 2019 05:25 |
|
I'm struggling to interpret what you're doing but removing the await will just mean that you continue execution in the current context while the task is performing work. If you never await it then you can't guarantee the work will be done when you want it to. I assume you're not using the return value immediately otherwise you'll see a bunch of type errors as the result will be a Task instead of your type.
|
# ? Oct 15, 2019 05:50 |
|
Xik posted:I'm struggling to interpret what you're doing but removing the await will just mean that you continue execution in the current context while the task is performing work. I can try to show more but at the some point, the context gets overwhelming. I'm trying to write an embeddable interpreter using something like a Python 3 syntax. I intend to have it run a pile of scripts as their own coroutines and am trying to use async-await to make it work. The first await is the scheduler awaiting for the currently-scheduled coroutine--as a Task--to unblock. The second level of await is a wrapper to turn everything the scheduler sees into what looks like continuations. Custom awaiters will inform the scheduler they are blocking and file the continuation it gets from OnCompleted with the scheduler using this general mechanism. However, to make things more uniform, new coroutines are launched in the same way--except that the continuation in their case is the initial start of their code. The third level of the await is the interpreter itself running into a custom WAIT opcode I created to have the current script yield for a tick. It is awaiting on a custom awaiter that files the continuation with the scheduler that'll just line it up to run on the next tick. When run that way, it deadlocks. However, if I remove the await from the second level, it doesn't. It hurts my head. All unit tests are passing this way. Most are just running in one tick, but I threw in that WAIT opcode particularly to make sure I can create some blocking calls that will stop interpreting on one script while having the scheduler just move on. This all seems to work with that. In fact, I also fixed the issue with multiple ticks tonight so it's pretty much working like I would have wanted it to. I just can't explain to myself how I stripped away that await keyword to do it.
|
# ? Oct 15, 2019 06:13 |
|
I don't have any experience with async-await (though I read a whole bunch of Fabulous Adventures in Coding shortly before the feature was added to C#), but it seems to me that if you fix things by causing the second level of task to just fire off into the ether instead of awaiting it, there's a problem with the thread continuing when the task completes. Did you test what happens if you docode:
|
# ? Oct 15, 2019 15:42 |
|
Jethro posted:I don't have any experience with async-await (though I read a whole bunch of Fabulous Adventures in Coding shortly before the feature was added to C#), but it seems to me that if you fix things by causing the second level of task to just fire off into the ether instead of awaiting it, there's a problem with the thread continuing when the task completes. Did you test what happens if you do I hadn't tested it since there is a very specific pattern I'm requiring at the bottom level and it's not that. But I see your point and I might force it for the sake of shenanigans. That specific pattern could have a flaw. I also agree with your idea that without the await on the second level, I should be just flinging that code out into the void... yet that doesn't appear to happen. What seems to happen is: The scheduler continues to block until the WAIT is processed It finishes its tick loop the continuation of the script is put into the active queue (since WAIT blocks 1 tick) In the second tick loop, it finishes it. Two ticks--as expected in this particular scenario; all other scenarios tick just once since they don't block midway. For more details on the mess, imagine I'm creating a game script to run some dialogs: code:
(this is all on GitHub so I get to just link to it all!) 1. The first await is the scheduler letting the script run synchronously. 2. The second level is a wrapper to run the script as a general continuation. This is because .NET's INotifyCompletion's OnCompleted() gives me a continuation to resume and I didn't want to manage two code paths. So I treat starting a new script as if I'm resuming it from it's main entry point. This continuation originally awaited on the script but doesn't any more. 3. The third level await in this case would be on a external function call that processes announce(). What I link here is the WAIT opcode I'm using in my current test, though. Since it wouldn't be finished in this tick, the internals will implement a customer awaiter (YieldTick version used in WAIT scenario here) so it can harvest the continuation .NET gives to OnCompleted(). This is shuffled back to the scheduler and put in a blocked queue. When the command does complete, the scheduler gets notified to run it again, and it will resume the continuation on the next tick. I am proceeding to implement a mock test for this scenario. I scratched something up to do this exact thing without the interpreter in between and it did work then. Adding in the actual interpreter and its scheduling of course adds in many more moving parts, and one of them is that second-level wrapper. So I suppose I'll have a real test seeing how that behaves and maybe that'll explain it. PS Sorry if this is crazy dense. This has been some brain-bendy poo poo and I didn't get this far without prototyping a simpler scenario first. Even that was rough on my brain. This is me messing around with toy projects after 11PM and the other side of my brain takes over and Mr. Hyde comes out.
|
# ? Oct 15, 2019 17:49 |
|
raminasi posted:Some of them also do stupid poo poo like demand that you remove "unnecessary" async despite the semantics of It actually makes quite a difference. async keyword instructs compiler to build a state machine to process continuation of the awaited task. Consider this simple example: C# code:
code:
code:
|
# ? Oct 18, 2019 00:11 |
|
Xik posted:I think the idea of that suggestion is that you should really make sure that's what you want to be doing. Like, is there a reason you're using await, maybe just return the task so the caller can decide. We bring it in as a StyleCop rule that isn't a "suggestion." It breaks the build unless you go out of your way to disable it. (This might be a stupid Rider thing, I don't know.) And the caller can't decide anything in this case - all it sees is a Task. Chrungka posted:It actually makes quite a difference. async keyword instructs compiler to build a state machine to process continuation of the awaited task. Consider this simple example: It also makes "quite a difference" in that the semantics are different, which is the thing I was posting about but I guess you ignored because you wanted to show off that you knew how to disassemble things.
|
# ? Oct 18, 2019 05:26 |
|
/simpsons voice/ Ha-ha! Whenever I think of giving a try to static analysis, I get put off by "rules" that are more like "Are you sure?" suggestions and I have always had to go through some extra effort because yeah, actually I am sure. The only time static analysis ever proved useful to me was when I accidentally captured the foreach variable way back when they were not per-iteration but per-foreach scoped. What kind of errors do you guys actually catch with static analysis? On another topic, is there some good "practical C#" learning book for beginners? I am training some newbies and all books I can find are the most boring drivel that just goes through language features one by one, including all the bullshit language features nobody should use in 2019. I can just see the book authors taking the C# language docs TOC and just slamming chapters into their book for each TOC entry just to pad their page count. Is there a beginner book that focuses on actually achieving things with code, not just mindless language exercises?
|
# ? Oct 18, 2019 07:18 |
|
Anyone used OpenTK? I have some problems with audio recording, namely getting stuff from the OpenAL buffers into something like a memory stream. There are a lot of moving parts in the library and I don't really know how to glue them all together.
|
# ? Oct 18, 2019 08:42 |
|
hangfire allows you to create queues, allowing you to process different background jobs on different hangfire servers hangfire makes it sound like these queues work properly and predictably and as you'd expect hangfire loving lies
|
# ? Oct 18, 2019 09:49 |
|
redleader posted:hangfire allows you to create queues, allowing you to process different background jobs on different hangfire servers I haven't looked at in a while, but from what I remember, somewhere in the documentation it gives the caveat that all your background tasks must be idempotent because they could be interrupted at any time and then it'll retry them. It seemed like that warning should have been a lot more prominent though as it is somewhat at odds with the marketing message of easily backgrounding all your tasks.
|
# ? Oct 18, 2019 11:53 |
|
EssOEss posted:What kind of errors do you guys actually catch with static analysis? The Roslyn team used static analysis to ensure that when your method accepts a CancellationToken but you fail to pass it on to a Cancellation-token-taking method that your invoking, then it's likely an oversight and should be fixed. It's an issue because so many .NET framework methods have overloads which allow you to omit the cancellation token. (also for perf things, since they needed their inner-loops not to allocate gratuitously e.g. $"hello {i}" needlessly boxes the int while $"hello {i.ToString()}" doesn't, but that's pretty niche).
|
# ? Oct 18, 2019 12:37 |
|
zerofunk posted:caveat that all your background tasks must be idempotent because they could be interrupted at any time and then it'll retry them LOL. Don't use a baby's-first-queue like Hangfire; just invest the time to layer in Azure Service Bus or RabbitMQ. These give you infinitely more options regarding how queue messages are completed/aborted/retried, and don't tie you tightly to a particular implementation (assuming you abstract away the queue message receiver and queue message specifics.)
|
# ? Oct 18, 2019 15:26 |
|
ljw1004 posted:The Roslyn team used static analysis to ensure that when your method accepts a CancellationToken but you fail to pass it on to a Cancellation-token-taking method that your invoking, then it's likely an oversight and should be fixed. Oh, that's a nice one! Is this one of the default rules or available on NuGet? -- On another topic, is there some obvious direction to go if I want a minimum effort CRUD website against some data source (e.g. SQL)? I just want something quick and dirty that throws up a database table as a data grid and lets users mess with it as if they were using Excel (in fact, this is a workflow that's done in Excel today). This data is used as input to drive some automation processes. All my work so far has been on products with more involved requirements than "just let users do whatever with the raw data", so I am not sure what fills this niche. My fallback option is just to stick the input data into some JSON/XML file in a Git repository and tell users to mess with that but I feel like this might be too big of a detraction from Excel for some users.
|
# ? Oct 19, 2019 20:07 |
|
When I try dotnet build I get this:code:
e: Command-line msbuild works. edit again: I'm trying to use the new Microsoft.NET.Sdk.WindowsDesktop in .NET Core 3, and apparently if I actually have a WPF control or window in my project this happens. Hooray! raminasi fucked around with this message at 23:17 on Oct 19, 2019 |
# ? Oct 19, 2019 22:48 |
|
EssOEss posted:On another topic, is there some obvious direction to go if I want a minimum effort CRUD website against some data source (e.g. SQL)? I just want something quick and dirty that throws up a database table as a data grid and lets users mess with it as if they were using Excel (in fact, this is a workflow that's done in Excel today). This data is used as input to drive some automation processes. All my work so far has been on products with more involved requirements than "just let users do whatever with the raw data", so I am not sure what fills this niche. FWIW, you can pull data right out of a DB with Excel using any extant view or a custom query. Not sure if you can persist back into the DB with Excel, though.
|
# ? Oct 21, 2019 14:36 |
|
EssOEss posted:On another topic, is there some obvious direction to go if I want a minimum effort CRUD website against some data source (e.g. SQL)? I just want something quick and dirty that throws up a database table as a data grid and lets users mess with it as if they were using Excel (in fact, this is a workflow that's done in Excel today). This data is used as input to drive some automation processes. All my work so far has been on products with more involved requirements than "just let users do whatever with the raw data", so I am not sure what fills this niche. If it's literally SQL and not a generic data source, https://www.adminer.org/en/editor/#download probably suits your needs. Demo: https://demo.adminer.org/editor.php?username=
|
# ? Oct 21, 2019 17:58 |
|
Is it possible to prevent reflection and serialization in singletons in C#?
|
# ? Oct 23, 2019 08:11 |
|
What is your goal here? Are you trying to prevent yourself from accidentally breaking the singleton contract by using reflection or serialisation internally? Are you trying to prevent malicious code from deliberately creating multiple singletons for some nefarious purpose? Are you trying to make it easier for benign-yet-incompetent developers to use your singleton the "right way" as opposed to hacking up a seemingly-working-until-it-doesn't solution using reflection?
|
# ? Oct 23, 2019 08:25 |
|
Jabor posted:What is your goal here? The second and third one, but mostly theoretical. I know that in Java you can use an enum to prevent both of these things, but C# doesn't support that.
|
# ? Oct 23, 2019 08:33 |
|
|
# ? Jun 7, 2024 16:36 |
|
You can put your singleton in an assembly with the DisablePrivateReflection attribute. Keep in mind that, like the Java solution, this doesn't stop anyone copying your code and changing it to allow what they want to do.
|
# ? Oct 23, 2019 08:44 |