|
Sab669 posted:Dumb Question: What exactly does Microsoft's Reference Source site show me? This one? code:
|
# ? Jun 1, 2017 17:07 |
|
|
# ? May 18, 2024 03:55 |
|
I did see that but I didn't think it was the same thing. The constructor defined on MSDN I'm referring to only takes 1 parameter, whereas that defines 4. So if you were to write: var x = new ZipArchive(myStreamObj) I don't really understand how that would end up calling the static OpenOnStream method. There's also a definition for private ZipArchive() which takes the same 4 args plus an additional bool. But ok, then where is the implementation for the Entries property or CreateEntry method? If internal static ZipArchive OpenOnStream is a constructor, then what is private ZipArchive? Why does the former include a return type as well as the name whereas the later only has the return type? The private ZipArchive method is what I'm "used to" for a constructor; you give it a scope and it returns an instance of itself. Why does the former have scope, return type and a name if it's a constrictor? Sab669 fucked around with this message at 17:44 on Jun 1, 2017 |
# ? Jun 1, 2017 17:38 |
|
That is in the namespace MS.Internal.IO.Zip I have no idea why the ones in MSDN (System.IO.Compression) aren't in there though.
|
# ? Jun 1, 2017 18:47 |
|
The .NET Core sources should be close enough https://github.com/dotnet/corefx/blob/master/src/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs
|
# ? Jun 1, 2017 20:15 |
|
I have always considered Reference Source to be a bit of an approximation. Interestingly enough, so is decompilation! There are methods that I have decompiled from .NET Framework assemblies themselves that end up differing in their runtime behavior, compared to the decompiled code. I can only gueess that there might be native-code variants of such functions switched in at runtime (or the decompiler in Reflector might just be buggy, I suppose?). For example, DateTimeOffset.ToUnixTimeMilliseconds() has a constant there to define the epoch. The constant visible in decompiled code is different from what is really used in practice. Thew me for a loop when I noticed my numbers were off!
|
# ? Jun 1, 2017 21:15 |
|
So LINQ to SQL can handle DateTime.AddHours just fine, but only AddHours I guess, because it throws errors on AddMinutes? I mean, fine, it's a one-line workaround. But what the gently caress? Why so oddly specific on only allowing AddHours?
|
# ? Jun 2, 2017 18:11 |
|
I've run into an weird/annoying problem trying to get a Winforms app working how (I think) it should. I'm trying to write a Winforms program to run as a TortoiseSVN client-side post-commit hook. I've created a new Winforms project using the default project template. This runs just fine from VS, and shows the (empty, completely untouched Form1) as you'd expect. If I set this same executable as a TortoiseSVN post-commit hook, the form simply doesn't show up. The program runs - I can see it in Task Manager (and have to kill it manually) - but the main form just doesn't display. However, if I then add a call to MesageBox.Show() before Application.Run() and run the program as a post-commit hook, the message box pops up, then the main form displays. Does anyone have any idea why showing the message box causes the form to show properly, or what I need to change to get the form to display when called from TortoiseSVN?
|
# ? Jun 5, 2017 07:25 |
|
This may be a stupid question, but did you make sure to have the "Hide the script while running" hook script option turned off? That's usually there to prevent the command window from popping up when executing a batch file or console application, but could also affect your WinForm. Showing the MessageBox might simply interfere with TortoiseSVN's attempt to hide the main process window, or reset some flag that caused it to be hidden before.
|
# ? Jun 5, 2017 10:57 |
|
SirViver posted:This may be a stupid question, but did you make sure to have the "Hide the script while running" hook script option turned off? That's usually there to prevent the command window from popping up when executing a batch file or console application, but could also affect your WinForm. Showing the MessageBox might simply interfere with TortoiseSVN's attempt to hide the main process window, or reset some flag that caused it to be hidden before. TortoiseSVN hangs with "hide script while running" turned on, presumably because it's waiting for the (invisible?) form to close. It works fine with the message box. e: haha, gently caress. Figured it out - I needed to uncheck "hide this script". Annoyingly, I have another hook that uses Winforms that needs this option selected. God, how dumb. redleader fucked around with this message at 22:33 on Jun 5, 2017 |
# ? Jun 5, 2017 22:26 |
|
So I asked another dev how their Winforms-based commit hook works. Turns out they hack it by having a timer call Form.Show() basically as soon as the program starts. Amazing. Beautiful. Elegant. I suspect that it might have something to do with the way TSVN redirects standard input/output/error combined with some wonderful legacy behavior, but can't prove it - and I don't the time, inclination, knowledge, or energy to investigate further.
|
# ? Jun 6, 2017 13:24 |
redleader posted:some wonderful legacy behavior I don't the time, inclination, knowledge, or energy to investigate further. Shame that's too long for a thread title.
|
|
# ? Jun 6, 2017 15:22 |
|
redleader posted:but can't prove it - and I don't the time, inclination, knowledge, or energy to investigate further. This speaks directly to my soul.
|
# ? Jun 6, 2017 18:59 |
|
Have an async question. When returning a value that doesn't require a long running operation (e.g. something local or in a cache or whatever), should I return the value directly or wrap it in an "await Task.FromResult"? Best I can tell is that the IL for these two examples are exactly the same. Is this code just trivial enough for the compiler to be taking shortcuts, or is there really no difference between the two? Directly code:
code:
|
# ? Jun 6, 2017 20:11 |
|
Duct Tape posted:When returning a value that doesn't require a long running operation (e.g. something local or in a cache or whatever), should I return the value directly Yes because why overcomplicate matters by adding some pointless level of indirection that may or may not get compiled away as the compiler goes "wtf bro".
|
# ? Jun 6, 2017 20:24 |
|
EssOEss posted:Yes because why overcomplicate matters by adding some pointless level of indirection that may or may not get compiled away as the compiler goes "wtf bro". Yeah, this is my stance as well. I was just worried that I was unintentionally breaking the state machine for more-complex methods by not wrapping trivial results in Task.FromResult. Doesn't sound like that's the case, though.
|
# ? Jun 6, 2017 21:07 |
|
Duct Tape posted:
This just adds unnecessary complexity, and makes things harder to read.
|
# ? Jun 6, 2017 21:20 |
|
I need to upgrade a dll from 4.0 framework to 4.6, however I have to keep backwards compatibility for 4.0. From what I'm reading this should work if I only use 4.0 stuff on the 4.0 machines. Can anyone confirm this? I don't need 4.6 installed on those machines to continue to use 4.0 features correct? The dll will load without the new framework installed? So the dll moving forward will target 4.6. And I will put that dll on machines which only have 4.0 installed. Someone please tell me this will work!
|
# ? Jun 6, 2017 21:41 |
|
Essential posted:I need to upgrade a dll from 4.0 framework to 4.6, however I have to keep backwards compatibility for 4.0. From what I'm reading this should work if I only use 4.0 stuff on the 4.0 machines. Can anyone confirm this? I don't need 4.6 installed on those machines to continue to use 4.0 features correct? The dll will load without the new framework installed? I guess it might work, because the frameworks from 4.0 onwards were in-place upgrades, but this is a terrible idea and you are very likely to regret it. You have a number of much safer options available, and if you give more details we could suggest the right one. Probably the easiest solution involving the least amount of work would be to split off the 4.6-exclusive features into their own library (which references the 4.0 library), and only install that additional library on the machines that can support it.
|
# ? Jun 6, 2017 21:58 |
|
NihilCredo posted:I guess it might work, because the frameworks from 4.0 onwards were in-place upgrades, but this is a terrible idea and you are very likely to regret it. Basically we have software that targets 4.0 distributed all across the country, so I don't have physical access to them. Moving forward, for async/await features (among other things) we need to upgrade to 4.6. We can't use the 4.0 async BCL library because of a few issues. The whole system is built on the same update framework, so as soon as we publish the 4.6 dll all the distributed systems will get it. I was hoping to avoid having 2 different frameworks to maintain. Hopefully that explains it enough, I can provide more details if necessary.
|
# ? Jun 6, 2017 22:25 |
|
Essential posted:I need to upgrade a dll from 4.0 framework to 4.6, however I have to keep backwards compatibility for 4.0. From what I'm reading this should work if I only use 4.0 stuff on the 4.0 machines. Can anyone confirm this? I don't need 4.6 installed on those machines to continue to use 4.0 features correct? The dll will load without the new framework installed? If you move that library to 4.6 any machine without 4.6 will error on running the app even if you don't use features beyond the version installed. I haven't done any serious async stuff yet so not sure if this would work, but could you build new async lib in 4.6 that includes/wraps the existing lib and then extends it? It seems this is what NihilCredo is suggesting as well.
|
# ? Jun 6, 2017 23:49 |
|
GoodCleanFun posted:If you move that library to 4.6 any machine without 4.6 will error on running the app even if you don't use features beyond the version installed. Got it. I thought what I was reading told me otherwise, but makes sense. Yeah I think extending the library and/or wrapping it is an option. I'm not quite sure how to go about this though, would appreciate any feedback anyone has.
|
# ? Jun 6, 2017 23:57 |
|
Duct Tape posted:Yeah, this is my stance as well. I was just worried that I was unintentionally breaking the state machine for more-complex methods by not wrapping trivial results in Task.FromResult. Doesn't sound like that's the case, though. It will make it throw warnings though, which is mildly annoying. In most cases I've run into (return null because method shouldn't do anything, or because conditions aren't met, etc) since it's always the same value, I've used Task.FromResult. The created Task is reused so there's no downside other than readability. However, if you're not using await and are getting a Task from somewhere (including Task.FromResult), you can just remove the async modifier and return the Task directly without awaiting it. So: code:
|
# ? Jun 7, 2017 07:52 |
|
Duct Tape posted:Have an async question. When returning a value that doesn't require a long running operation (e.g. something local or in a cache or whatever), should I return the value directly or wrap it in an "await Task.FromResult"? The method doesn't need to be async since all it does is decide which task to return. You can simplify it like this: code:
Of course, you can't do this if you wanted to do something in this method with the result of the long running operation before returning it to the caller. Edit: yeah what he said ^^
|
# ? Jun 7, 2017 10:14 |
|
Red Mike posted:Supposedly it has some effect on where exceptions would be thrown, but I've yet to run into a case where it actually matters myself. It makes exceptions throw immediately, instead of faulting the returned Task. This normally isn't a huge deal if all you're doing is code:
|
# ? Jun 7, 2017 12:53 |
|
I'm getting some loving weird behaviour with Fluent Validation and MVC I hope you guys can help with. I've got a very simple validator with only 5 rules: code:
Also, in the view, the validation messages for the date and times have the "text-danger" class, while the ones generated for ServiceId and Animals don't. Clearly, those 2 sets of rules are being processed differently somehow, seemingly in 2 different passes. I presumed that the date and time fields were getting validated client side, and so the other rules weren't getting processed if they failed - however, in either case, the POST does actually hit the controller action before being validated and returned, which I believe doesn't happen if client side fails, as it prevents the POST from occuring? Also, I tried disabling client-slide validation completely, and saw the same behaviour. Probably also worth mentioning that I was originally using NotNull for ServiceId (which did cause client side validation to occur), and NotEmpty for Animals, which gave the same behaviour, before I switched them to using Must(). Does anyone have any insight as to what's going on here? e: I just changed them all to 'must' rules and got the exact same behaviour. What the actual gently caress. chippy fucked around with this message at 21:24 on Jun 7, 2017 |
# ? Jun 7, 2017 21:16 |
|
Night Shade posted:It makes exceptions throw immediately, instead of faulting the returned Task. This normally isn't a huge deal if all you're doing is Yeah, except in all the practical cases I've seen during reviews, it wouldn't have mattered anyway because the code itself was badly designed and had major flaws besides this. The situation you mention would have been replaced at code review stage in all the codebases I've worked with, because you don't just turn a list of URLs into a list of parallel downloads like that, you call an async method of your own that does its own try/catching (and probably other functionality). I'm sure there must be cases where it is a concern, which is why I mentioned it in the first place. Also, in the 'orphaned tasks' situation, you normally just hit the default uncaught exception handler. Wouldn't crash your app, same as throwing in an async void wouldn't.
|
# ? Jun 7, 2017 21:36 |
|
Maybe it's because it's the end of the day and my brain is fried but I'm not seeing why a WebApi controller I added as a quick and dirty proxy for our weather data provider isn't getting routed:C# code:
|
# ? Jun 7, 2017 21:41 |
|
Setting the contrivance of .Select(DownloadParallel) aside, if you're kicking off parallel Tasks at some point in the call chain you need to not be awaiting them immediately regardless of how smart the Task-returning method is. This makes the difference in exception propagation significant. e: because i can trust that an async method won't throw until the Task is observed and is therefore safe to pass directly to .Select / Seq.map / whatever. I can't say the same about a non-async method that happens to return Task.Red Mike posted:Also, in the 'orphaned tasks' situation, you normally just hit the default uncaught exception handler. Wouldn't crash your app, same as throwing in an async void wouldn't. https://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception(v=vs.110).aspx posted:This event provides notification of uncaught exceptions. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application. Night Shade fucked around with this message at 05:14 on Jun 8, 2017 |
# ? Jun 8, 2017 05:11 |
|
Night Shade posted:Setting the contrivance of .Select(DownloadParallel) aside, if you're kicking off parallel Tasks at some point in the call chain you need to not be awaiting them immediately regardless of how smart the Task-returning method is. This makes the difference in exception propagation significant. e: because i can trust that an async method won't throw until the Task is observed and is therefore safe to pass directly to .Select / Seq.map / whatever. I can't say the same about a non-async method that happens to return Task. That's fair enough, I guess. I've still yet to run into this case in the wild, so you can just mentally remove 'Supposedly' from my first post. quote:Huh, I stand corrected. I'm not sure what ASP.NET and the two other server techs we've used do then, because we've got those events for safety/logging, but uncaught exceptions never cause issues (unless they're actual hard faults). e: And similarly in Unity on the client-side, actually, but that doesn't have async/await anyway.
|
# ? Jun 8, 2017 07:47 |
|
Red Mike posted:Huh, I stand corrected. I'm not sure what ASP.NET and the two other server techs we've used do then, because we've got those events for safety/logging, but uncaught exceptions never cause issues (unless they're actual hard faults).
|
# ? Jun 8, 2017 10:19 |
|
chippy posted:I'm getting some loving weird behaviour with Fluent Validation and MVC I hope you guys can help with. If anyone's interested, I think these two posts may hold the answers. The first one even has the same tone of confused frustration as I do. https://github.com/JeremySkinner/FluentValidation/issues/127 https://github.com/JeremySkinner/FluentValidation/issues/130
|
# ? Jun 8, 2017 11:30 |
|
Red Mike posted:Also, in the 'orphaned tasks' situation, you normally just hit the default uncaught exception handler. Wouldn't crash your app, same as throwing in an async void wouldn't. I don't think that's right... Up to VS2012 (.NET4), a task that ended in the "failed" state and which was never observed (i.e. no one ever did .ContinueWith on it) would raise the global unhandled exception handler. But as of VS2012 (.NET4.5), once async/await was introduced, that behavior didn't make sense. So we removed it. We specifically wanted to support patterns like this, which never signs up anything for after JonesAsync. code:
code:
What does that do? It varies. I remember trying it inside WPF, Winforms and UWP (each have their own slightly different synchronization context). I remember that there were different behaviors between the three -- ignored? pop up an error dialog? terminate the program? -- but I can't remember which. I think they all involve the unhandled exception filter first. What does it do when there's no synchronization context, i.e. it hits the threadpool? I think that goes down the unhandled exception filter route and then terminates the program, but can't remember. What does it do in the ASP.NET synchronization context? I don't know.
|
# ? Jun 8, 2017 14:07 |
|
Munkeymon posted:Maybe it's because it's the end of the day and my brain is fried but I'm not seeing why a WebApi controller I added as a quick and dirty proxy for our weather data provider isn't getting routed: The problem was that when I pasted the API URL into Postman, it 'helpfully' prepended an extra [url]http://[/url] that I didn't notice until this morning ASP still won't route something that looks like a number to {*url} though. I hate the way ASP does routing e: Really anything in .Net that's run-it-and-see-if-it-works is maddening because that's what a compiler is supposed to be for Munkeymon fucked around with this message at 15:33 on Jun 8, 2017 |
# ? Jun 8, 2017 15:17 |
|
Munkeymon posted:ASP still won't route something that looks like a number to {*url} though. I hate the way ASP does routing For example, if your route looks like api/myroute/{part1}/{part2}, with part1+2 being string variables, you get:
|
# ? Jun 8, 2017 15:36 |
|
SirViver posted:Also quite fun if you want to route something that may have a "." in the URL content. Tinkering with it, it appears to be the second one. I'm just going to make a slightly smarter proxy, I guess, because it's just not loving worth it to monkey with the whole site for this.
|
# ? Jun 8, 2017 15:42 |
|
ljw1004 posted:I don't think that's right... This is really good info, thanks. I'll forward it to my team and check with the server software we use so we can figure out what they do (if anything) so we're at least aware of what could happen. If nothing else, this entire exchange has convinced me that I should pay more attention to this and maybe add specifics to the guidelines instead of relying just on the code reviewer catching it. Re: the initial bit though, does that mean that unobserved faulted tasks have no ill effects, so the original situation with the Select wouldn't have any issues (other than the exception being thrown where you might not expect)?
|
# ? Jun 8, 2017 17:56 |
|
ljw1004 posted:Up to VS2012 (.NET4), a task that ended in the "failed" state and which was never observed (i.e. no one ever did .ContinueWith on it) would raise the global unhandled exception handler. Ah cool. I've been operating under the belief the .NET 4 behaviour was still the current behaviour. Cunningham's Law in action Red Mike posted:Re: the initial bit though, does that mean that unobserved faulted tasks have no ill effects, so the original situation with the Select wouldn't have any issues (other than the exception being thrown where you might not expect)? Seems that way. That's a relief. You're still left with something blowing up Select itself instead of blowing up when the resulting Tasks are awaited, but that's something you can handle in code, not something that will kill your app at some indeterminate point in the future. e: actually if Select blows up you may well be left with work happening inside Tasks that you no longer have any way of dealing with unless you've got a CancellationTokenSource you can use to abort them. Night Shade fucked around with this message at 23:11 on Jun 8, 2017 |
# ? Jun 8, 2017 23:03 |
|
Night Shade posted:e: actually if Select blows up you may well be left with work happening inside Tasks that you no longer have any way of dealing with unless you've got a CancellationTokenSource you can use to abort them. Honestly, edge cases like this are part of the reason why I said code like this wouldn't make it past review at my workplace. If you just wrap whatever you're calling into a task of your own with proper error handling then suddenly it's a null point because you've fixed both the exception case and the fact that the exception isn't thrown in the place you'd expect. And one of the guidelines already is "expect any async method to later turn into a sync one with no work done other than removing the await", so yeah. I do now feel like this is yet another gotcha with regards to async/await that isn't highlighted enough even as an edge case.
|
# ? Jun 9, 2017 07:57 |
|
What's up with C#'s list constructor returning void?code:
quote:Cannot implicitly convert type 'void' to 'System.Collections.Generic.List<ThingType>' Is it just a dumb pattern to try and initialize it and add something at the same time without using an initializer? It's not like I can pass something into the constructor. Is this working pattern better? If so, why? code:
|
# ? Jun 9, 2017 17:46 |
|
|
# ? May 18, 2024 03:55 |
|
itskage posted:What's up with C#'s list constructor returning void? You're trying to capture the return of the Add method, which is void. Just do new List<ThingType> { thing };
|
# ? Jun 9, 2017 17:56 |