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
Eldred
Feb 19, 2004
Weight gain is impossible.

redleader posted:

async/await in old-timey asp.net (.aspx, .ashx, .asmx) is a minefield, but i agree that in this case async is the wrong approach. personally, i'd use hangfire because i hate myself and enjoy the ease of getting started combined with the unintuitive behavior in edge cases

Can you expand a bit on the unintuitive behavior? I have a task where something like the delayed jobs would be perfect and want to find the landmines ahead of time :)

Adbot
ADBOT LOVES YOU

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
Does anyone know when they plan to ship .NET 5 with Windows itself?

CapnAndy
Feb 27, 2004

Some teeth long for ripping, gleaming wet from black dog gums. So you keep your eyes closed at the end. You don't want to see such a mouth up close. before the bite, before its oblivion in the goring of your soft parts, the speckled lips will curl back in a whinny of excitement. You just know it.

spaced ninja posted:

Haven’t used EF in a while but pretty sure this is what you want. You can auto generate the entities from the db.

https://docs.microsoft.com/en-us/ef/ef6/modeling/designer/workflows/database-first
I started looking into this, and of course it's EF 6, not EF Core. I'm also trying to move to .NET 5, because I might as well rip off as many bandaids as possible at once and learn the stuff Microsoft's gonna demand I learn anyway. I guess I have to learn scaffolding too now?

epswing
Nov 4, 2003

Soiled Meat

CapnAndy posted:

I'm also trying to move to .NET 5, because I might as well rip off as many bandaids as possible at once

This is likely going to be my strategy as well, jumping from .NET Framework 4.8 straight to .NET 5, skipping Core entirely.

mystes
May 31, 2006

epalm posted:

This is likely going to be my strategy as well, jumping from .NET Framework 4.8 straight to .NET 5, skipping Core entirely.
.Net 5 is basically .net core 3.2 anyway.

Cold on a Cob
Feb 6, 2006

i've seen so much, i'm going blind
and i'm brain dead virtually

College Slice

mystes posted:

.Net 5 is basically .net core 3.2 anyway.

Yeah at this point I’m sticking to the LTS versions for this reason.

LongSack
Jan 17, 2003

Is there a good way to generate / present dynamically generated images in ASP.Net core? I have an idea for a demo web app that shows the Mandelbrot set, Julia sets, and diamond/square displacement generated random height maps.

The goal would be for the user to be able to drag-select sections of the images to zoom in.

In my WPF version, I used a WritableBitmap in an unsafe block. I believe that the WritableBitmap class still exists in .Net 5, but I’m not sure if/how it lives in the ASP.Net core ecosystem.

Is there a good solution to this? TIA

Edit: there are two questions here: (1) how do I generate dynamic images at the pixel level, and (2) how do I present these images to the user from an API

LongSack fucked around with this message at 05:48 on Jan 13, 2021

Eldred
Feb 19, 2004
Weight gain is impossible.

LongSack posted:

Is there a good way to generate / present dynamically generated images in ASP.Net core? I have an idea for a demo web app that shows the Mandelbrot set, Julia sets, and diamond/square displacement generated random height maps.

The goal would be for the user to be able to drag-select sections of the images to zoom in.

In my WPF version, I used a WritableBitmap in an unsafe block. I believe that the WritableBitmap class still exists in .Net 5, but I’m not sure if/how it lives in the ASP.Net core ecosystem.

Is there a good solution to this? TIA

Edit: there are two questions here: (1) how do I generate dynamic images at the pixel level, and (2) how do I present these images to the user from an API

WPF support in .NET Core is kind of rough, IIRC there's a useWPF flag you can set at the csproj level but only certain project SDKs can support that and web is not one of them (unless that's changed with 5).

It's ugly but you could create a separate csproj with your WPF functions and invoke them from your web project. Might be better to try to replicate your functionality with ImageSharp or another library.

mystes
May 31, 2006

I don't think you want to invoke wpf or gdi drawing functions from a web server. They really aren't intended for that. It might actually be less gross if you were using the compatibility package on linux but there's still no real reason to do that.

Serving the resulting images will be trivial.

Whether you really want to do this on the server in the first place is another question.

mystes fucked around with this message at 06:46 on Jan 13, 2021

redleader
Aug 18, 2005

Engage according to operational parameters

Eldred posted:

Can you expand a bit on the unintuitive behavior? I have a task where something like the delayed jobs would be perfect and want to find the landmines ahead of time :)

i'm exaggerating a bit tbh. there are a couple of annoying things we've run into here with hangfire, like:

  • we have two different servers with different assemblies deployed that used one db (and ⚠️one hangfire schema⚠️). this meant that jobs queued on one server occasionally ran on the other - which failed because the assembly from the other server wasn't present. clearly user error, and obvious in retrospect! but i am an idiot. make sure your hangfire servers and clients use the same codebase, which is easy if you're just doing some background processing on a single machine (or a few machines using the same codebase). we solved the problem using a different queue for each machine. in retrospect i should have just created different hangfire schemas, ehhh. but queues bring me to:
  • hangfire queues are a little weird and are clearly a late addition to hangfire. we use queues to separate machines and prioritise tasks - but if a task fails and gets retried, it gets queued back onto a default queue, not the original one! bear this in mind if you want to use queues for priority control or whatever. i found a thing somewhere that fixes this, but i still don't 100% trust things

i mean it's fine enough, and does its job - especially for simple use cases. i'm just a little bitter since i seem to have ended up as the hangfire toucher :shrug:

general advice:

  • make sure your methods are idempotent since hangfire will retry failed jobs a few times by default
  • your hangfire'd methods should only take in "simple" objects that can be easily and safely (de)serialized to/from json, since that's how hangfire stores params internally. think dto-style objects
  • be careful changing code. if a job has been enqueued and you deploy a change to the method (changing params, renaming, removing etc, heck, even changing its behavior), it could fail or go wrong in obvious or annoying ways. ideally you want to keep the old method+behavior long enough for all the relevant enqueued jobs to finish. or you could just not care and yolo it (as we do)
  • figure out how to get hangfire logs into your logging system because they will fail pretty much invisibly otherwise

overall i'd rate it as "fine, and i'd rather use it than roll my own equivalent"


mystes posted:

I don't think you want to invoke wpf or gdi drawing functions from a web server. They really aren't intended for that. It might actually be less gross if you were using the compatibility package on linux but there's still no real reason to do that.

Serving the resulting images will be trivial.

Whether you really want to do this on the server in the first place is another question.

yeah, you don't want to gdi on a web server. it works most of the time, except when it doesn't and you get mysterious access violation exceptions that take down the app pool and it does that for years because no one cares enough to fix it

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

CapnAndy posted:

I started looking into this, and of course it's EF 6, not EF Core. I'm also trying to move to .NET 5, because I might as well rip off as many bandaids as possible at once and learn the stuff Microsoft's gonna demand I learn anyway. I guess I have to learn scaffolding too now?

FYI, you can use EF6 with .NET 5. I use .NET 5 + ASP.NET Core 5 + EF6. The lack of designer support is one of the main things keeping us away from EF Core.

epalm posted:

This is likely going to be my strategy as well, jumping from .NET Framework 4.8 straight to .NET 5, skipping Core entirely.

I also did this, but it was mostly a question of timing. The moment we were ready to go to Core happened to be right around the time 5 came out. There was no substantial difference between 4.8->Core 3.0 and 4.8->5.0 for us.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



redleader posted:

yeah, you don't want to gdi on a web server. it works most of the time, except when it doesn't and you get mysterious access violation exceptions that take down the app pool and it does that for years because no one cares enough to fix it

Is System.Drawing a GDI wrapper? I've used that to generate images, but I think that was as part of a batch job.

mystes
May 31, 2006

Munkeymon posted:

Is System.Drawing a GDI wrapper? I've used that to generate images, but I think that was as part of a batch job.
Yes

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

CapnAndy posted:

I started looking into this, and of course it's EF 6, not EF Core. I'm also trying to move to .NET 5, because I might as well rip off as many bandaids as possible at once and learn the stuff Microsoft's gonna demand I learn anyway. I guess I have to learn scaffolding too now?

You can use EF Core with database first. I do and love it. I miss the gui\designer with scaffolding the database that was available before core, but the command line still beats building it all from scratch.

https://www.entityframeworktutorial.net/efcore/create-model-for-existing-database-in-ef-core.aspx

EssOEss
Oct 23, 2006
128-bit approved
There is ImageSharp which is not great but also not terrible, depending on how modest your drawing needs are.

Calidus
Oct 31, 2011

Stand back I'm going to try science!
I did the whole System.Drawing from a MVC back in 2012 for an internal MVC app. Recent graduate me was really proud. It was good enough for a internal app that only 20 concurrent users at a time. JavaScript and SVG are my go to for dynamic images now.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
What's recommended for capturing keyboard selection of listview items with WPF? I implemented PreviewKeyDown to do it and I wanted to make sure that was reasonable.

Something that isn't reasonable is some shenanigans I got trying to use that with Noesis in Unity3d. It has an idea of a GamepadAccept binding to select GUI elements, and I'm manually toggling it when the bindings to submit to the GUI in my code are toggled. In my case, the E key would do it for the keyboard as well as some button on the controllers I've tried. This somehow shows up in my PreviewKeyDown as a spacebar. I mean, I guess that would be normal in a standalone application? But just imagine I hit E and the debugger takes over and shows me this shiny space bar enum instead.

LongSack
Jan 17, 2003

OK, so I’ve abandoned my web-based graphics demo. I’m replacing it with a fictional online store. My current design has 3 front ends - Blazor server for customers, Blazor WASM for the employee portal, and MVC for the vendor portal (hey, it’s a demo app, why not?).

The back end is going to be implemented as an API fronting a series of independent “micro” services (for some value of micro) each with its own database and communicating via Azure Service Bus.

So here is my dilemma and my question. How do I balance the independence of my services with the DRY principle? For example, I have an extension method that I use extensively:
C# code:
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string order, bool descending)
{
    //
    // this code from StackOverflow.com answer to this question: 
    //   [url]https://stackoverflow.com/questions/7265186/how-do-i-specify-the-linq-orderby-argument-dynamically[/url]
    //

    string command = descending ? "OrderByDescending" : "OrderBy";
    var type = typeof(T);
    var property = type.GetProperty(order);
    var parameter = Expression.Parameter(type, "p");
    var propertyAccess = Expression.MakeMemberAccess(parameter, property);
    var orderByExpression = Expression.Lambda(propertyAccess, parameter);
    var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },
        source.Expression, Expression.Quote(orderByExpression));
    return source.Provider.CreateQuery<T>(resultExpression);
 }
It doesn’t make sense to me to duplicate this method in each service, but at the same time, if I put it into a common library, then that’s a dependency.

Currently I’m using a common library, but only putting things in it which are very unlikely to change, but I’m wondering if there’s a better solution

NihilCredo
Jun 6, 2011

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

LongSack posted:

but at the same time, if I put it into a common library, then that’s a dependency.

And... that would be bad because... ? :raise:

Really, a stateless generic function is the platonic ideal of a chill dependency. Make a
.NET Standard library, call it MyProject.Utils, and put all code like this in it. No state, no Nuget packages other than the very basics, easy to test (doesn't need mocks).

Calidus
Oct 31, 2011

Stand back I'm going to try science!
I have a TypeScript interface that is used for configuration, It uses DUs. Whats least terrible way to use that model in C#? JObject? Dynamic?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

LongSack posted:

if I put it into a common library, then that’s a dependency.


So? There's nothing wrong with common dependencies as long as you use proper semantic versioning.

The example you provided looks like it's never going to change. Pop it into a NuGet package that's referenced by any and all consumers.

LongSack
Jan 17, 2003

NihilCredo posted:

And... that would be bad because... ? :raise:

Really, a stateless generic function is the platonic ideal of a chill dependency. Make a
.NET Standard library, call it MyProject.Utils, and put all code like this in it. No state, no Nuget packages other than the very basics, easy to test (doesn't need mocks).

OK, I’ll keep going with the common library. Just need to make sure that stuff in there is very - not sure what the word is ... static? Things like Attributes, ValidationAttributes, and extension methods.

New Yorp New Yorp posted:

So? There's nothing wrong with common dependencies as long as you use proper semantic versioning.

The example you provided looks like it's never going to change. Pop it into a NuGet package that's referenced by any and all consumers.

Not gonna do a NuGet package, since (at least that code) isn’t mine. Class library is it.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

LongSack posted:

Not gonna do a NuGet package, since (at least that code) isn’t mine. Class library is it.

If you're doing this, you should do it right. The provenance of the code doesn't matter, it should be a versioned NuGet package. You can have a private NuGet feed. Hell, a file share or local folder can be a NuGet feed. But using a NuGet package allows consumers of the package to pin their required version so that you're free to evolve the package and introduce changes (including breaking changes in a new major version) without impacting all consumers.

NihilCredo
Jun 6, 2011

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

OTOH, if the only users of that library are a few projects that live within the same repository, and they all share the same release pipeline (this is important), then a NuGet package is overkill and simple project-to-project references are totally fine.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

NihilCredo posted:

OTOH, if the only users of that library are a few projects that live within the same repository, and they all share the same release pipeline (this is important), then a NuGet package is overkill and simple project-to-project references are totally fine.

Back to my "if you're going to do it, do it right" commentary: At this point, you're not really writing microservices anymore, you're writing a monolith that has pieces that talk to each other over HTTP.

brap
Aug 23, 2004

Grimey Drawer
Choose a more complex solution with additional capabilities you don’t need, otherwise you are making “bad thing” instead of “good thing”

EssOEss
Oct 23, 2006
128-bit approved

New Yorp New Yorp posted:

Back to my "if you're going to do it, do it right" commentary: At this point, you're not really writing microservices anymore, you're writing a monolith that has pieces that talk to each other over HTTP.

Which, speaking of doing things right, is often more right than splitting a service up into microservices just because that's what all the blog posts are speaking about. Aint nothing wrong with well-engineered monoliths.

No Pants
Dec 10, 2000

please stop building distributed monoliths, i'm dying

WorkerThread
Feb 15, 2012

No Pants posted:

please stop building distributed monoliths, i'm dying

no

redleader
Aug 18, 2005

Engage according to operational parameters

No Pants posted:

please stop building distributed monoliths, i'm dying

the future is now, old man

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

EssOEss posted:

Which, speaking of doing things right, is often more right than splitting a service up into microservices just because that's what all the blog posts are speaking about. Aint nothing wrong with well-engineered monoliths.

I don't disagree. There's a lot of additional complexity involved in creating a robust microservice architecture and I honestly rarely (never) see it done well.

I'll stand by my prior statement that common code being distributed via versioned packages that strictly follow semver is a requirement.

WorkerThread
Feb 15, 2012

New Yorp New Yorp posted:

I don't disagree. There's a lot of additional complexity involved in creating a robust microservice architecture and I honestly rarely (never) see it done well.

I'll stand by my prior statement that common code being distributed via versioned packages that strictly follow semver is a requirement.

If the debugging experience didn't suck so much, maybe I'd be more sympathetic to packaging everything. But a shared library for a single solution? Nah. Definitely all hassle for zero upside.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

WorkerThread posted:

If the debugging experience didn't suck so much, maybe I'd be more sympathetic to packaging everything. But a shared library for a single solution? Nah. Definitely all hassle for zero upside.

You can include debug symbols in packages. I do it all the time.

WorkerThread
Feb 15, 2012

New Yorp New Yorp posted:

You can include debug symbols in packages. I do it all the time.

For a long time, my environment was sdk style projects on the full framework, where even if you included symbols in the packages, Visual Studio refused to load them. So maybe things are better now but I still don't really trust the half baked package manager that .Net decided to marry for some reason.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I think if there's more than one team consuming the assembly then it should definitely be a versioned NuGet package. If there's only one team then it depends on how the assembly is used by that team. If it's used within a single solution then there's no need to overcomplicate things (making it a versioned package opens up the possibility that "project X.ABC is using version 2.1 but project X.DEF is stuck on 1.5 and we forgot about the difference and it led to bugs" - terrible). If it's used by more than one solution and the solutions are more or less unconnected to one another then it should be a versioned package, because you don't want to have to update stuff in various unrelated solutions any time you change something for the solution you're working on right now; you shouldn't even have to keep track of that in your head.

Making something a separately maintained package instead of just a class library project in the solution is extra overhead, so you shouldn't do it just for the heck of it, but you should do it if the circumstances indicate that it's the right thing to do.

zokie
Feb 13, 2006

Out of many, Sweden
At my last job they tried to do “micro services”.

Everything was a separate package (like multiple per solution), and because there were so many of them they made a custom tool that automatically bumped all versions that ran automatically on build. And the services were more vertically distributed that horizontal. No they didn’t distribute them with symbols, the responsible developers didn’t even know you could!! When I had to help them with some bug I had to have 4 different solutions open to have access to all the code involved.

The whole thing included highlights like health checks every 5 seconds that generated an exception so the first thing you had to do when checking the logs was to filter them out.

Cold on a Cob
Feb 6, 2006

i've seen so much, i'm going blind
and i'm brain dead virtually

College Slice
That sounds like hell.

I'm the principal services dev at my small-ish company. Our development team is around ~24 developers and analysts. Early on I made the decision to use a single shared core library we call ApiCore as their foundation. It simplifies things a lot. If you need to debug something in ApiCore you just reference the ApiCore project directly. Since it's just one library it's very easy to maintain a set of unit and integration tests so it's proven very stable. I think we've had maybe two support issues for it in the last 12 months, outside of upgrade testing.

I'm sure a lot of microservice architecture astronauts would turn up their noses at it but we're now 5 years in with 15+ services* built without any major support issues or controversy. Obviously there is a scale where this approach could run into problems but we can just split it if that ever happens to us. We have our issues as a team and as a company but the core library and services architecture ain't one of them. :shobon:

* Our services are neither micro nor monolithic; we try to define them based on logical boundaries of business function. In other words, this library underpins a lot of code.

CapnAndy
Feb 27, 2004

Some teeth long for ripping, gleaming wet from black dog gums. So you keep your eyes closed at the end. You don't want to see such a mouth up close. before the bite, before its oblivion in the goring of your soft parts, the speckled lips will curl back in a whinny of excitement. You just know it.
I'm at my wit's end, can anyone explain to me how this is escaping error handling and what I can do to corral it? I have tested it with async code that does nothing but throw an exception and it can catch that, but when I do the HttpClient.GetAsync and it exceptions out, it's busting straight through.

code:
try
{
	Task.Run(async () =>
	{
		result = await client.GetAsync(url);
	}).Wait();
}
catch (Exception ex)
{
	//error handling
}

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

CapnAndy posted:

I'm at my wit's end, can anyone explain to me how this is escaping error handling and what I can do to corral it? I have tested it with async code that does nothing but throw an exception and it can catch that, but when I do the HttpClient.GetAsync and it exceptions out, it's busting straight through.

code:
try
{
	Task.Run(async () =>
	{
		result = await client.GetAsync(url);
	}).Wait();
}
catch (Exception ex)
{
	//error handling
}

Async void methods are a footgun for precisely this reason. The way the exception is rethrown is through the task. Without a task, it can't rethrow.

Adbot
ADBOT LOVES YOU

CapnAndy
Feb 27, 2004

Some teeth long for ripping, gleaming wet from black dog gums. So you keep your eyes closed at the end. You don't want to see such a mouth up close. before the bite, before its oblivion in the goring of your soft parts, the speckled lips will curl back in a whinny of excitement. You just know it.

Bruegels Fuckbooks posted:

Async void methods are a footgun for precisely this reason. The way the exception is rethrown is through the task. Without a task, it can't rethrow.
Okay, but what am I supposed to do about it? I don't even want to be calling the dang website asynchronously in the first place, the code's not doing anything until it gets that data, but HttpClient only frigging has GetAsync for reasons that are certainly beyond me.

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