Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Jabor
Jul 16, 2010

#1 Loser at SpaceChem
That article is poorly written, the code it supplies is not how anyone would write it in a modern language, and I'm not sure anyone who learned programming this century would ever call it the "command pattern" anyway.

It's literally just like writing an event handler in javascript. When you create your event handler, nothing happens right away - you just get something you can invoke later that will do the thing you've specified. You pass that something to the system, and the system then invokes it at an appropriate time.

Adbot
ADBOT LOVES YOU

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Yeah sorry I should've said that my interest comes from this book which discusses it:

https://gameprogrammingpatterns.com/command.html

but treating it like a event handler works. I think I have a better grasp of it now in literally treating it like MVC.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

worms butthole guy posted:

Yeah sorry I should've said that my interest comes from this book which discusses it:

https://gameprogrammingpatterns.com/command.html

but treating it like a event handler works. I think I have a better grasp of it now in literally treating it like MVC.

That page does a much better job of motivating it and talking about why you'd use it and why various aspects are there. I'd honestly suggest re-reading that page and mulling over it some more instead of looking for explanations on SEO content mill websites.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
yeah ill do that - I was having trouble equating some of the C or whatever language in there into C# but I think I can get a hand of it now!

Baby Proof
May 16, 2009

Now to complicate things a bit specifically in .NET, the ICommand interface includes both invoking the request and a CanExecute property. This can be useful if you want to use the same object for both triggering the action and displaying whether the action can be initiated (for example when a Command is attached to a command button, it might enable/disable based on CanExecute). But the command pattern is useful for more situations than the .NET Command classes, and even when using .NET Commands I often ignore the CanExecute part.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
...I didn't know there was a .Net command class rip

ulmont
Sep 15, 2010

IF I EVER MISS VOTING IN AN ELECTION (EVEN AMERICAN IDOL) ,OR HAVE UNPAID PARKING TICKETS, PLEASE TAKE AWAY MY FRANCHISE

worms butthole guy posted:

my question, and I hope I explain this correctly, is - why would pass the receiver to the command instead of just calling the function on the receiver in the first place? I.e. why do:

I think your second link summed it up, but just passing "commands" to the receiver means that it's much easier to write the receiver ("command.doYourThing"), and also means that you can more easily add things like a replay feature (after all, now you have a list of objects you just play from start to finish) and an undo feature (not so much for a game, but now you have a list of commands to just say "command.undoYourThing").

And of course your input processing now only has to know enough to build a command and send it on, rather than mixing its device-interaction with other parts of the code.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Thank you for that. I tried to use it with a input handler last night but ran into syntax errors lol. Oh well, wil ltry again today.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
spending some time getting my head around this new crazy stuff they added to c#

code:
namespace ConsoleApp1;

public static class Program
{
    public static void Main(string[] args)
    {
        F<MyInterfaceImplementer1, int>(69);
        F<MyInterfaceImplementer1, int>(420);
        F<MyInterfaceImplementer2, string>("very nice");
        Console.ReadLine();
    }

    public static void F<TThis, TImplicitPrecursor>(TImplicitPrecursor p) where TThis: IMyInterface<TThis, TImplicitPrecursor>
    {
        var t = (TThis)p;
        Console.WriteLine(t.ToString());
    }

    public interface IMyInterface<TThis, TImplicitPrecursor> where TThis: IMyInterface<TThis, TImplicitPrecursor>
    {
        static abstract implicit operator TThis(TImplicitPrecursor precursor);
    }

    public class MyInterfaceImplementer1: IMyInterface<MyInterfaceImplementer1, int>
    {
        public int X { get; }

        public static implicit operator MyInterfaceImplementer1(int x)
            => new MyInterfaceImplementer1(x);

        public MyInterfaceImplementer1(int x)
        {
            X = x;
        }

        public override string ToString()
        {
            return $"{nameof(MyInterfaceImplementer1)}({X})";
        }
    }

    public class MyInterfaceImplementer2: IMyInterface<MyInterfaceImplementer2, string>
    {
        public string X { get; }

        public static implicit operator MyInterfaceImplementer2(string x)
            => new MyInterfaceImplementer2(x);

        public MyInterfaceImplementer2(string x)
        {
            X = x;
        }

        public override string ToString()
        {
            return $@"{nameof(MyInterfaceImplementer2)}(""{X}"")";
        }
    }
}

cruft
Oct 25, 2007

Is there a way to dump the number of active tasks?

I'm trying to add some debugging to Jellyfin to figure out a bug that I suspect is related to too many tasks and not enough threads in the Thread Pool.

I fully expect the actual issue is going to take 3 months just to locate, but this feels like the right place to start. Unfortunately, I've never written C# before, so I'm hoping this quick check can at least tell me if I'm on the right track, before I dive too deep into understanding .NET's TPL.

Red Mike
Jul 11, 2011

cruft posted:

Is there a way to dump the number of active tasks?

I'm trying to add some debugging to Jellyfin to figure out a bug that I suspect is related to too many tasks and not enough threads in the Thread Pool.

I fully expect the actual issue is going to take 3 months just to locate, but this feels like the right place to start. Unfortunately, I've never written C# before, so I'm hoping this quick check can at least tell me if I'm on the right track, before I dive too deep into understanding .NET's TPL.

So far I've gone through about five attempts at figuring out a way to get this information, or instrumenting the TPL so that this info gets output to a performance counter or Datadog or something. There just isn't a useful way to do this generically. This is made doubly worse if you happen to be running something that changes the synchronisation context like legacy ASP.NET compatibility mode, or a UI application, etc. Also, trying to instrument/get this information is going to require a lot of bizarre .NET knowledge, so if you've never written C# before I really recommend against trying to dive into internals.

The closest was the answer to this question I asked on SO, but what it doesn't mention is that the TPL's events aren't super consistent and don't emit in the way you would expect (or at least there's no spec that defines it in a way that makes sense). If your code isn't doing anything particularly weird, that approach may work to figure out what's happening.

I haven't dug into the bug to see what it's about but my recommendation would be to ignore the TPL and try to instrument the app side of it (basically keep track of when tasks are started/finished and keep a count of it within your own application, in some enable-able debug mode).

e: One approach I had some luck with was to instrument the TPL bits on the app side of it, i.e. have your own TaskRunner and/or a Task subclass that gets used in your library/application and instruments things; however you can't know what a library you call will do, and there's limited ways for you to change that.

Red Mike fucked around with this message at 10:35 on Feb 4, 2023

Mr Shiny Pants
Nov 12, 2012

cruft posted:

Is there a way to dump the number of active tasks?

I'm trying to add some debugging to Jellyfin to figure out a bug that I suspect is related to too many tasks and not enough threads in the Thread Pool.

I fully expect the actual issue is going to take 3 months just to locate, but this feels like the right place to start. Unfortunately, I've never written C# before, so I'm hoping this quick check can at least tell me if I'm on the right track, before I dive too deep into understanding .NET's TPL.

This might be helpful: https://learn.microsoft.com/en-us/dotnet/core/diagnostics/debug-threadpool-starvation

Ruud Hoenkloewen
Jan 24, 2020
Hey, everyone. At my current place I've been given free reign over the next month or two to modernise our codebase, which is ~100 projects mostly on Framework 4.8. I'm mainly trying to get us onto .NET 6, but are there any easy wins I should consider for getting code quality up alongside that? Some things I've done already:

- Enable non-null ref types for the big projects, started annotating some types
- Added analysers for bad async/await usage, fixed some obvious errors
- Purged all our dead/duplicate code (there was... a lot of it)
- Breaking up god classes

Things I'm planning on but haven't done yet:
- Get dotnet format running in our CI pipeline
- Start getting stuff running in Docker (one of the business' motivations for this whole thing)
- Find more analysers? I've not used them much before, so I don't know which are particularly good

The team isn't bad but don't really consider code quality unless the computer shouts at them about it, so automated stuff is probably the way to go.

Mega Comrade
Apr 22, 2004

Listen buddy, we all got problems!
Good list. One thing I don't see mentioned is an editor config.

Arguing with developers about coding style is a pain in the arse. Stick wiggly red lines under their bad styling and they will just fix it without much fuss.

cruft
Oct 25, 2007


:aaa:

Thanks to both of you for your insight! It's great to know this is Non-Trivial™, but that MS article seems super helpful for exactly what I'm struggling with.

Ruud Hoenkloewen
Jan 24, 2020

Mega Comrade posted:

Good list. One thing I don't see mentioned is an editor config.

Arguing with developers about coding style is a pain in the arse. Stick wiggly red lines under their bad styling and they will just fix it without much fuss.

Thanks, that's a good idea. We actually do have an .editorconfig in the solution, but I don't think it's actually used for much (even tabs, lol).

epswing
Nov 4, 2003

Soiled Meat

Ruud Hoenkloewen posted:

Get dotnet format running in our CI pipeline

Mega Comrade posted:

Arguing with developers about coding style is a pain in the arse.

Oh cool, didn’t know dotnet format existed. Back when I was writing a lot of Python, introducing Black to some projects was a breath of fresh air, not a single millisecond wasted thinking about style, just type and everything formatted on save. It was great.

Mr Shiny Pants
Nov 12, 2012

cruft posted:

:aaa:

Thanks to both of you for your insight! It's great to know this is Non-Trivial™, but that MS article seems super helpful for exactly what I'm struggling with.

Np, I had a look through the codebase, but it is pretty spread out. Any idea where this code would be? Just for my own personal curiosity. :)

cruft
Oct 25, 2007

Mr Shiny Pants posted:

Np, I had a look through the codebase, but it is pretty spread out. Any idea where this code would be? Just for my own personal curiosity. :)

For this particular bug, I suspect that "scanning" is exhausting threads. My plan was to just periodically log how many pending tasks there were, then start a scan and see whether that number jumps really high.

I've chased a few pointers and I think PerformLibraryValidation in Emby.Server.Implementations/Library/LibraryManager.cs is where it starts. That calls PerformLibraryValidation on the root folder, which I think eventually makes it to ValidateChildrenInternal2 in MediaBrowser.Controller/Entities/Folder.cs.

I think the problem might happen when there are a bunch of subfolders, which triggers a ton of async Tasks to fire up in order to recurse into them. I'm guessing wildly here, not really understanding how .NET does anything, really. I suppose it should be simple enough to set up a deeply-nested directory structure vs a shallow one to test this out, though. I might do this when I get home tonight...

Red Mike
Jul 11, 2011

cruft posted:

I think the problem might happen when there are a bunch of subfolders, which triggers a ton of async Tasks to fire up in order to recurse into them. I'm guessing wildly here, not really understanding how .NET does anything, really. I suppose it should be simple enough to set up a deeply-nested directory structure vs a shallow one to test this out, though. I might do this when I get home tonight...

That's probably a good guess. As a general rule unless/until I run into performance issues, I try to keep async things linear for exactly this reason. One Task starts and awaits one Task. If there's a small bit of processing where I want to parallelise, I try to make sure the parallel work does not itself also spawn new Tasks. That way, you generally end up with a pipeline of a small number of Tasks for each incoming request/action/etc. It then also becomes really obvious where the bottleneck is.

This kind of problem tends to happen as soon as you have Tasks that might spawn multiple Tasks simultaneously which themselves might also spawn multiple Tasks simultaneously; or rarely, cases where the parallel Tasks end up being indirectly locking each other by accessing shared resources (e.g. Disk IO). If the folder/library data isn't being loaded ahead of the parallel Tasks and passed in, then this could be what's happening too. (you ask it to check 1000 files in parallel, there's only so many simultaneous reads that can happen at once, and unless the async function awaits/yields before the heavy processing once the read is done...then you've got 995 files waiting to be read but stuck spinning because the 5 ongoing tasks are doing heavy processing and not yielding).

brap
Aug 23, 2004

Grimey Drawer
Agree with the above. Presumably many peoples media libraries are on spinning disks where I think trying to parallelize accesses may not improve performance. Consider modifying the implementation to do its traversal linearly and see what happens to the I/O perf.

If investing in high performance for this is found to be necessary then specialized solutions which use specific features of underlying file system might make sense. Consider how freaking fast WizTree is for example.

Mr Shiny Pants
Nov 12, 2012

cruft posted:

For this particular bug, I suspect that "scanning" is exhausting threads. My plan was to just periodically log how many pending tasks there were, then start a scan and see whether that number jumps really high.

I've chased a few pointers and I think PerformLibraryValidation in Emby.Server.Implementations/Library/LibraryManager.cs is where it starts. That calls PerformLibraryValidation on the root folder, which I think eventually makes it to ValidateChildrenInternal2 in MediaBrowser.Controller/Entities/Folder.cs.

I think the problem might happen when there are a bunch of subfolders, which triggers a ton of async Tasks to fire up in order to recurse into them. I'm guessing wildly here, not really understanding how .NET does anything, really. I suppose it should be simple enough to set up a deeply-nested directory structure vs a shallow one to test this out, though. I might do this when I get home tonight...

I would keep it simple stupid. Just do everything sequentially at first. :) If you run into perf issues you can always do some funky stuff.

Might even be something like DB updates bottlenecking each other.

Calidus
Oct 31, 2011

Stand back I'm going to try science!
Find all uses of ParallelForEach, it’s an amazing foot gun. I may have caused socket exhaustion on a server by using it in my early 20s.

raminasi
Jan 25, 2005

a last drink with no ice

I’m sad I’m leaving my .NET job before I get to play with this stuff :(

Chasiubao
Apr 2, 2010


cruft posted:

Is there a way to dump the number of active tasks?

I'm trying to add some debugging to Jellyfin to figure out a bug that I suspect is related to too many tasks and not enough threads in the Thread Pool.

I fully expect the actual issue is going to take 3 months just to locate, but this feels like the right place to start. Unfortunately, I've never written C# before, so I'm hoping this quick check can at least tell me if I'm on the right track, before I dive too deep into understanding .NET's TPL.

I'm late to this but there are some well-known .NET runtime performance counters for thread pool queue length and thread count which are emitted by default. https://learn.microsoft.com/en-us/dotnet/core/diagnostics/available-counters I'm newer to .NET Core and it does seem like there are fewer useful counters by default compared to FX, but this might get you started as well?

Canine Blues Arooo
Jan 7, 2008

when you think about it...i'm the first girl you ever spent the night with

Grimey Drawer

raminasi posted:

I’m sad I’m leaving my .NET job before I get to play with this stuff :(

I left .NET for a year and immediately missed it. I'm back in it now and am not anxious to leave. I'm so sorry I betrayed you - never again!

raminasi
Jan 25, 2005

a last drink with no ice

Chasiubao posted:

I'm late to this but there are some well-known .NET runtime performance counters for thread pool queue length and thread count which are emitted by default. https://learn.microsoft.com/en-us/dotnet/core/diagnostics/available-counters I'm newer to .NET Core and it does seem like there are fewer useful counters by default compared to FX, but this might get you started as well?

I was going to say, I remember getting a lot of mileage out of staring at a Datadog dashboard with exactly the requested metrics on it, but I was on my phone and it was a couple years ago so I didn't post.

Chasiubao
Apr 2, 2010


raminasi posted:

I was going to say, I remember getting a lot of mileage out of staring at a Datadog dashboard with exactly the requested metrics on it, but I was on my phone and it was a couple years ago so I didn't post.

:hf: I waited until I was at a desktop before I responded or even looked for that link

Mr Shiny Pants
Nov 12, 2012

Canine Blues Arooo posted:

I left .NET for a year and immediately missed it. I'm back in it now and am not anxious to leave. I'm so sorry I betrayed you - never again!

Even with all the stupid poo poo MS does I really do like programming in it.

Baby Proof
May 16, 2009

I've got a simple Windows CE application that I'm thinking about porting to Android. Has MAUI gotten any better? I tried it when it left beta and immediately started hitting bugs.
The smart answer would be to do it in Xamarin (even though I don't know that at all) but I'm tempted by the new and shiny.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Baby Proof posted:

I've got a simple Windows CE application that I'm thinking about porting to Android. Has MAUI gotten any better? I tried it when it left beta and immediately started hitting bugs.
The smart answer would be to do it in Xamarin (even though I don't know that at all) but I'm tempted by the new and shiny.

IMO, if you can swing it, I would use .NET Android SDK straight (AKA what post-.NET 6 Xamarin.Android is now). It's harder to build, but you'll have a better Android app since it's tied to the platform and not on abstractions. When you use these abstractions that try to make Android/iOS/macOS development more like Windows, you usually end up having to hack the underlying framework to make the thing not operate like it's on Windows, if that makes sense. It's more trouble than it's worth.

Having said that, If you're okay with a drawn framework and don't require native controls, Avalonia's mobile support is getting pretty good and a good fit if you know WPF. Uno is also okay, and it's stable. And as someone who has contributed to the MAUI project and is working to help fix issues in it, I would advise staying away unless it's an app you're screwing around with and don't depend your business on. While it needs feedback and more testing, IMO I wouldn't want to subject others to dealing with the pain right now.

LongSack
Jan 17, 2003

Baby Proof posted:

I've got a simple Windows CE application that I'm thinking about porting to Android. Has MAUI gotten any better? I tried it when it left beta and immediately started hitting bugs.
The smart answer would be to do it in Xamarin (even though I don't know that at all) but I'm tempted by the new and shiny.

If you’re only concerned about Android, I’d lean toward going native with Kotlin and Jetpack Compose. In my experience, the hardest part was getting the dependencies correct using Gradle. Android Studio its free and its not a bad IDE IMO. (If you’re curious, you can find babby’s first mobile app here)

Of course, if you intend to go multi-platform, then that’s not a good choice.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost
Xamarin.Android is excellent, IMO, for building an Android app in .NET. You don't need to build a "cross-platform UI" app in .NET. You can always build directly to the platform using the bound SDKs and IMO that will build the best apps no matter what. Cross-platform toolkits have their place and are great tools, but you'll always be making a compromise.

Ruud Hoenkloewen
Jan 24, 2020

Mega Comrade posted:

Good list. One thing I don't see mentioned is an editor config.

Arguing with developers about coding style is a pain in the arse. Stick wiggly red lines under their bad styling and they will just fix it without much fuss.

Just want to say thanks for this, after a little arguing I got something in place and everything is looking much neater now :)

Now to see if I can get some actual tests in place for this thing...

Baby Proof
May 16, 2009

Drastic Actions posted:

Xamarin.Android is excellent, IMO, for building an Android app in .NET. You don't need to build a "cross-platform UI" app in .NET. You can always build directly to the platform using the bound SDKs and IMO that will build the best apps no matter what. Cross-platform toolkits have their place and are great tools, but you'll always be making a compromise.

I'm willing to compromise quite a bit on UI if it means being able to do most initial testing and debugging in windows, but it turns out Motorola has a Xamarin Android library for interfacing to their barcode scanner, so that's probably the direction I'm going. Thanks for the input.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

I know this is the .NET thread, but if you know modern c# and you only want to write an Android app (as opposed to any kind of cross-platform project), I'd just take the opportunity to write it in Kotlin. Learning the language is not going to take much longer than learning the Xamarin conventions, and it's a far more valuable skill to have.

riichiee
Jul 5, 2007
I'm in need of a bit of advice.

I need to create a a scheduling tool, and since I've got an average amount of experience in C# / WPF, I'm going to create a desktop WPF application.

The app would essentially consist of a DataGridView, the rows of which would be populated from an Azure SQL Table that contains a list of projects.

The columns would each represent a day, with the user being able click into a cell, marking them as busy for that day. The projects are big enough so that they can be broken down into day tasks, no need for hours etc..

I don't really want to re-invent the wheel, so is there an open source control that might do this?

Also, the last WPF / MVVM project I wrote was back in 2018(?), is it worth investigating WinUI3?

Also, is a DataGridView the best tool for this?

Any help is appreciated!

Canine Blues Arooo
Jan 7, 2008

when you think about it...i'm the first girl you ever spent the night with

Grimey Drawer
My take would be that unless you are building something cross platform, there is no reason to not use WPF.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

riichiee posted:


I don't really want to re-invent the wheel, so is there an open source control that might do this?

Evaluate what existing software will meet your needs before you write a line of code. What are you scheduling, and why do none of the dozens of existing solutions that can manage calendars and scheduling meet your requirements?

Adbot
ADBOT LOVES YOU

bobua
Mar 23, 2003
I'd trade it all for just a little more.

riichiee posted:

I'm in need of a bit of advice.

I need to create a a scheduling tool, and since I've got an average amount of experience in C# / WPF, I'm going to create a desktop WPF application.

The app would essentially consist of a DataGridView, the rows of which would be populated from an Azure SQL Table that contains a list of projects.

The columns would each represent a day, with the user being able click into a cell, marking them as busy for that day. The projects are big enough so that they can be broken down into day tasks, no need for hours etc..

I don't really want to re-invent the wheel, so is there an open source control that might do this?

Also, the last WPF / MVVM project I wrote was back in 2018(?), is it worth investigating WinUI3?

Also, is a DataGridView the best tool for this?

Any help is appreciated!

If you are looking for an actual calendar, you could use something like syncfusions(free community edition i think) or devexpress's scheduler. https://www.syncfusion.com/wpf-controls/scheduler
They have different viewmodes you can work with, if one gets close to your needs I'd just adapt it.

I've recently been working on a really weird one. Have a company that's been sheduling via excel for decades, so they want a program that feels exactly like what they get from excel. All sorts of weird stuff based on days, teams, projects, and trucks... not time of day like a normal schedule. Plus the infinite color coding\labeling\formatting of excel cells. It made more sense to just build the controls and do the drag and drop from scratch.


  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply