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
Iverron
May 13, 2012

SirViver posted:

I'm by no means an expert on async, but as far as I can tell your problem (besides the lack of curly brace placement) is that you're still running your code synchronously. Specifically you're calling onTick.Invoke(), which is a synchronous call and therefore negates all the async/awaits you plastered around your code.

This gives the wrong impression I think. A synchronous call will cause an asynchronous method to behave synchronously for the duration of the synchronous call.

code:
        private async void button1_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            Farts service = new Farts();
            var contentTask = service.GetContentAsync();
            var countTask = service.GetCountAsync();
            var nameTask = service.GetNameAsync();

            var content = await contentTask;
            Console.WriteLine(watch.ElapsedMilliseconds);
            var count = await countTask;
            Console.WriteLine(watch.ElapsedMilliseconds);
            var name = await nameTask;
            Console.WriteLine(watch.ElapsedMilliseconds);

            watch.Stop();
            Console.WriteLine("done");
        }

...

    public class Farts
    {
        public async Task<string> GetContentAsync()
        {
            await Task.Delay(2000);
            Thread.Sleep(2000); //sync call
            return "Fart";
        }

        public async Task<int> GetCountAsync()
        {
            await Task.Delay(5000);
            return 4;
        }

        public async Task<string> GetNameAsync()
        {
            await Task.Delay(3000);
            return "Butt";
        }
    }
The above output would look something like "4000 5000 5000".

The awaits aren't negated per say (that reads to me as though the output might be "4000 9000 9000"), but there is some UI hanging around that 2-4 second mark and expected delay on the completion of the first awaited async call.

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice
code:
1>typecheck error FS0193: error : Index was outside the bounds of the array.
1>typecheck error FS0193: error : Index was outside the bounds of the array.
1>typecheck error FS0193: error : Index was outside the bounds of the array.
1>typecheck error FS0193: error : Index was outside the bounds of the array.
1>typecheck error FS0193: error : Index was outside the bounds of the array.
1>typecheck error FS0193: error : Index was outside the bounds of the array.
1>typecheck error FS0193: error : Index was outside the bounds of the array.
1>parameter error FS0193: error : Index was outside the bounds of the array.
Who's got two thumbs and somehow triggered a fsc.exe bug that replaced all compiler error messages with ArgumentOutOfRangeExceptions?

Sab669
Sep 24, 2009

So last month I did basically nothing but dick around with an array of static code analyzers. Particularly looking for Security vulnerabilities in our flagship product.

Very few security issues were found, except for 1 rule which says methods which return a ActionResult object should be marked with [HttpGet], or in a select few cases it suggested [HttpPost].

Problem is, the analyzer doesn't take any consideration of how the javascript / cshtml is written and invokes any of these methods. So sometimes an ajax request gets sent as Post from 1 page but sent as a Get from another. So loving nothing works because such-and-such method doesn't exist when you try to do anything [because of the Http* attribute on it].

I have absolutely no idea what the gently caress to do :suicide: Trying to unravel this and correct it is going to take forever, and even then I have no idea if this will do gently caress all for the security of the application.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Sab669 posted:

So sometimes an ajax request gets sent as Post from 1 page but sent as a Get from another.

This is the problem. Fix that problem. GET and POST have very specific usages and aren't interchangeable. Or at least they shouldn't be.

Sab669
Sep 24, 2009

The issue is that we paid some Indian firm to rewrite our entire application last year. It's pretty large. And it's basically just me that maintains it.

So I have no idea what they did. Not intimately familiar with ASP MVC, although I understand MVC principals. Third party controls I've never used before.A handful of custom controls that I have minimal understanding of how it was cobbled together. The entire application is all stitched together so that page virtually never fully reloads, it just makes Ajax calls and updates the HTML of one div. So since the URL in the address bar never changes I don't really get how / why anything should ever be sent as a Get request in our case.

jony neuemonic
Nov 13, 2009

Sab669 posted:

So since the URL in the address bar never changes I don't really get how / why anything should ever be sent as a Get request in our case.

Apologies if this is something you already have a handle on but, just for clarity: You know that AJAX calls can send GET or POST (or PUT or DELETE or whatever...) requests totally independently of what's in the URL bar yeah?

redleader
Aug 18, 2005

Engage according to operational parameters

Sab669 posted:

The issue is that we paid some Indian firm to rewrite our entire application last year. It's pretty large. And it's basically just me that maintains it.

So I have no idea what they did. Not intimately familiar with ASP MVC, although I understand MVC principals. Third party controls I've never used before.A handful of custom controls that I have minimal understanding of how it was cobbled together. The entire application is all stitched together so that page virtually never fully reloads, it just makes Ajax calls and updates the HTML of one div. So since the URL in the address bar never changes I don't really get how / why anything should ever be sent as a Get request in our case.

Pick up Fiddler (or a similar web debugging proxy), and watch/gently caress around with HTTP requests in real time.

If you know what "page" makes a request but can't pinpoint the JS, use Chrome's dev tools to set a breakpoint on the AJAX XHR. Once you hit the breakpoint, you can easily look through the stack trace and find what function made the AJAX request. I'm hoping that your poo poo isn't totally hosed and that you'd be able to locate that function in an actual .js file somewhere.

Sab669
Sep 24, 2009

jony neuemonic posted:

Apologies if this is something you already have a handle on but, just for clarity: You know that AJAX calls can send GET or POST (or PUT or DELETE or whatever...) requests totally independently of what's in the URL bar yeah?

I do, yes, I just don't have any understanding of why the people who wrote it did things the way they did is all.

Kekekela
Oct 28, 2004

Sab669 posted:

I do, yes, I just don't have any understanding of why the people who wrote it did things the way they did is all.

There's an insane amount of cargo cult and cut/paste programming from those shops from what I've seen. There's likely no valid reason other than its how he got the code he was copying to work good enough to ship.

Sab669
Sep 24, 2009

You're absolutely right, and that's the problem. poo poo quality control and then a sole junior/mid level developer to maintain it :toot:

SirViver
Oct 22, 2008

Sab669 posted:

I do, yes, I just don't have any understanding of why the people who wrote it did things the way they did is all.

Sab669 posted:

The issue is that we paid some Indian firm to rewrite our entire application last year.

SirViver
Oct 22, 2008
Or to quote the ancient Chinese proverb:

no why

jony neuemonic
Nov 13, 2009

Sab669 posted:

I do, yes, I just don't have any understanding of why the people who wrote it did things the way they did is all.

Right on. redleader pretty much nailed it then, Fiddler and Chrome's dev tools are your best friends here. Good luck! :toot:

Sab669
Sep 24, 2009

Just reading up more on cross site request forgeries, I found an article on asp.net, as well as a few other random blogs, that talks about simply using @Html.AntiForgeryToken to prevent these types of attacks along with the [ValidateAntiForgeryToken] attribute. The code analyzer I used recommended the [HttpVerb] attributes as a solution.

I understand their purpose, so that a method can only be invoked by the designated request. But I'm not clear on how those attributes could really do much? Like hypothetically, say for some reason your Change Password page used a get request to update data... Whether it's attributed correctly or not, that's still kind of a giant security concern.

Are these attributes more of just a "good practice on top of other security / not poo poo code", or am I missing something? It seems like using the forgery token is more common / way loving easier. All of our views do make use of the antiforgery token, although searching the code for [ValidateAntiForgeryToken] yields exactly one result :v:

EssOEss
Oct 23, 2006
128-bit approved
The general principle is that code should be coded defensively - it should resist doing things it was not meant to do. If a thing should always be called via POST, it should yell and scream "Hey WTF are you doing" when you do a GET request to it, instead of silently accepting it. This is what the HttpVerb attribute enables one to achieve.

Yes, it does not change that a GET request for changing a password is retarded in many ways (and not only security).

Defensive coding such as this is often considered beneficial and occasionally even practiced. It depends on what standards one aspires to hold one's product to. No benchmark is absolute. Most code in the world is poo poo. The more you learn, the worse it is.

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
I'm trying to upgrade from Powershell to learning C#. Can I get a recommendation for a book or online course that will be good for someone who is a novice programmer?

raminasi
Jan 25, 2005

a last drink with no ice

Dr. Arbitrary posted:

I'm trying to upgrade from Powershell to learning C#. Can I get a recommendation for a book or online course that will be good for someone who is a novice programmer?

I've heard good things about this series of video tutorials from novices, although I've not reviewed them myself nor seen anything that the novices came up with after watching them.

chippy
Aug 16, 2006

OK I DON'T GET IT
Does anyone know of a good library for handling profit margin calculations and things in that sort of area?

spiderlemur
Nov 6, 2010
code:
var query = Butts.GroupBy(o => o.DateTime.Hour
		  .OrderBy(p => p.Key)
		  .Select(g => new List<int> { g.Key, g.Count() }).ToList();
EF query with weird results. The ordering of the inner list isn't preserved, and its elements can actually be swapped back and forth on each iteration. I needed a 2D Array for some Json, and List<List<int>> converted easily enough.

Selecting an anonymous object instead of new List<int> and then doing the copying in-memory works fine, and it can order groupings by that Key just fine.

I'm more interested in why EF can't deal with the original query, though. Basically "Group up every DateTime by their hour, and count each group. Put the results inside a collection.".

I'm not very good with SQL/LINQ stuff.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
I would try to look at what SQL is being generated - it might be an edge case for EF that it doesn't handle properly.

As a workaround, I would suggest something like this:

C# code:
var query = Butts.GroupBy(o => o.DateTime.Hour)
		  .OrderBy(p => p.Key)
		  .Select(g => new { g.Key, Count = g.Count() })
		  .AsEnumerable() // force db evaluation
		  .Select(g => new List<int> { g.Key, g.Count }) // build inner list in memory
		  .ToList(); 

spiderlemur
Nov 6, 2010
Sweet, kind of forgot about .AsEnumerable() to force evaluation. Looks way less weird than me busting out the for loops and newing up another List.

Faldoncow
Jun 29, 2007
Munchin' on some steak
Doing some WPF work and have a couple of questions that maybe someone has some advice on. First, I'm using a DataGrid to display a 2d array of data. However if I maximize the window (or have it at a high resolution), such that the DataGrid displays about 15+ columns and 40+ rows, the draw speed starts slowing down quickly. Is there any way to improve the draw speed, or a better Control I should be using?

Secondly, any tips on displaying large text files?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Faldoncow posted:

Doing some WPF work and have a couple of questions that maybe someone has some advice on. First, I'm using a DataGrid to display a 2d array of data. However if I maximize the window (or have it at a high resolution), such that the DataGrid displays about 15+ columns and 40+ rows, the draw speed starts slowing down quickly. Is there any way to improve the draw speed, or a better Control I should be using?

Secondly, any tips on displaying large text files?

Post an MVCE of the behavior you're talking about.

For the second question, it depends on your definition of "large" and what the contents of the text file would be. We need more context. What data is in the text file and what is your goal in displayin git?

NihilCredo
Jun 6, 2011

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

Bognar posted:

I would try to look at what SQL is being generated - it might be an edge case for EF that it doesn't handle properly.

As a workaround, I would suggest something like this:

Having never used EF, does the use of .AsEnumerable() to force evaluation do anything different from .ToArray() / .ToList() / .ToArbitraryDataStructure() ?

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

NihilCredo posted:

Having never used EF, does the use of .AsEnumerable() to force evaluation do anything different from .ToArray() / .ToList() / .ToArbitraryDataStructure() ?

It doesn't create an intermediate data structure that is immediately thrown away when you chain stuff onto it later. Also, it's a bit of a misnomer to say that it forces evaluation (my bad), since without calling .ToWhatever() afterwards it still won't evaluate. It just means that anything that follows will be executed in memory instead of being translated to SQL.

Faldoncow
Jun 29, 2007
Munchin' on some steak

New Yorp New Yorp posted:

Post an MVCE of the behavior you're talking about.

For the second question, it depends on your definition of "large" and what the contents of the text file would be. We need more context. What data is in the text file and what is your goal in displayin git?

Ignoring the text file for now, since it may end up irrelevant. So here's some sample code for displaying a DataGrid. Takes about 450ms on my computer to render the window when all the cells are visible. That may be standard, I'm just curious if there's any somewhat easy way to improve that performance.

MainWindow.xaml
code:
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        
        <Button Grid.Row="0" Click="Button_Click" Content="Refresh" Width="50" Height="20"/>
        <DataGrid Grid.Row="1" x:Name="_dataGrid" ItemsSource="{Binding Items}" />
    </Grid>
MainWindow.xaml.cs
C# code:
    public class RowDataItem
    {
        public List<int> Values { get; set; }
        static Random rand = new Random();

        public RowDataItem()
        {
            Values = new List<int>();
            for (int i = 0; i < 20; i++)
            {
                Values.Add(rand.Next() % 255);
            }
        }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<RowDataItem> Items { get; set; }
        Stopwatch watch = new Stopwatch();

        public MainWindow()
        {
            Items = new ObservableCollection<RowDataItem>();
            for (int i = 0; i < 50; i++)
            {
                Items.Add(new RowDataItem());
            }

            DataContext = this;
            InitializeComponent();

            for (int i = 0; i < 20; i++)
			{
                _dataGrid.Columns.Add(new DataGridTextColumn
                {
                    Header = i.ToString(),
                    Binding = new Binding(string.Format("Values[{0}]", i))
                });
			}
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            watch.Restart();
            _dataGrid.Items.Refresh();

            this.Dispatcher.BeginInvoke(
              DispatcherPriority.Render,
              new Action(() =>
              {
                  watch.Stop();
                  Console.WriteLine("Render Time: {0}ms", watch.ElapsedMilliseconds);
              }));
        }
    }

putin is a cunt
Apr 5, 2007

BOY DO I SURE ENJOY TRASH. THERE'S NOTHING MORE I LOVE THAN TO SIT DOWN IN FRONT OF THE BIG SCREEN AND EAT A BIIIIG STEAMY BOWL OF SHIT. WARNER BROS CAN COME OVER TO MY HOUSE AND ASSFUCK MY MOM WHILE I WATCH AND I WOULD CERTIFY IT FRESH, NO QUESTION

Bognar posted:

I would try to look at what SQL is being generated - it might be an edge case for EF that it doesn't handle properly.

As a workaround, I would suggest something like this:

C# code:
var query = Butts.GroupBy(o => o.DateTime.Hour)
		  .OrderBy(p => p.Key)
		  .Select(g => new { g.Key, Count = g.Count() })
		  .AsEnumerable() // force db evaluation
		  .Select(g => new List<int> { g.Key, g.Count }) // build inner list in memory
		  .ToList(); 

e: never mind I'm dumb

putin is a cunt fucked around with this message at 07:07 on Jan 12, 2017

epswing
Nov 4, 2003

Soiled Meat
I need to vent a little bit about Azure.

My web app sometimes throws these exceptions during a db transaction:

quote:

CommitFailedException: An error was reported while committing a database transaction but it could not be determined whether the transaction succeeded or failed on the database server. See the inner exception and http://go.microsoft.com/fwlink/?LinkId=313468 for more information. SqlException: Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding. Win32Exception: The wait operation timed out

The link suggests three options to deal with the problem:

quote:

In general when there is a connection failure the current transaction is rolled back. However if the connection is dropped while the transaction is being committed the resulting state of the transaction is unknown.

Option 1 - Do nothing ("it probably(!?) doesn't happen often so just let your app fail!")
Option 2 - Use the database to reset state ("write code for every transaction in your application to revert all possible database changes (if they occurred!), and inform the user that maybe(!?) the thing they just tried didn't work")
Option 3 - Manually track the transaction ("write a bunch of code to interact with a database table not tracked by EF to fix our lovely infrastructure that randomly times out several times a day leaving db transactions in an unknown state")

Totally 100% serious question: how exactly are ANY businesses writing mission-critical applications on this platform?

Edit: OK... I've calmed down a bit. I've opened 4 tickets in the last year regarding issues related to this problem, with no resolution. My web app still has issues committing database transactions, and it's infuriating because I have no control over the infrastructure these pieces use to talk to each other. I'm not doing anything fancy or weird, in fact I'm using Microsoft's web framework to talk to Microsoft's database via Microsoft's ORM, and it's all running on Microsoft's hosting platform, it really should all Just Work.

epswing fucked around with this message at 23:29 on Jan 12, 2017

rarbatrol
Apr 17, 2011

Hurt//maim//kill.
We have stuff that uses service bus, and it just sometimes craps out for no apparent reason. So we've written a wrapper around it where we just retry a handful of times before actually failing. I always assumed that's the cost of using their Platform As A Service.

john donne
Apr 10, 2016

All suitors of all sorts themselves enthral;

So on his back lies this whale wantoning,

And in his gulf-like throat, sucks everything

That passeth near.
All of your production code should be wrapped in failure recovery in any case. Transient errors should not cause an application to fall over.

Furism
Feb 21, 2006

Live long and headbang
How good is the "C# in Depth" book (http://csharpindepth.com) ? I'm looking for a good reference and best practices book.

ljw1004
Jan 18, 2005

rum

epalm posted:

Totally 100% serious question: how exactly are ANY businesses writing mission-critical applications on this platform?

??? Every mission-critical application is written with those same workarounds around that same issue.

What you describe is the fundamental law of distributed systems. "A given network operation either (1) succeeded and you know it, or (2) failed and you know it, or (3) you don't know whether it succeeded or fail". No amount of retry or subcomponents or "reliable transport layer" (a misnomer) will ever change this fact.

*** technically, the fact can be changed into "or you have to wait an unbounded length of time until you know whether it succeeded or failed" or "we have a 99.999% SLA and will issue refunds when (3) happens 0.001% of the time".

NihilCredo
Jun 6, 2011

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

This is why writing idempotent queries is so useful. Just log the error and retry that poo poo 100 times.

john donne
Apr 10, 2016

All suitors of all sorts themselves enthral;

So on his back lies this whale wantoning,

And in his gulf-like throat, sucks everything

That passeth near.

Furism posted:

How good is the "C# in Depth" book (http://csharpindepth.com) ? I'm looking for a good reference and best practices book.

Jon Skeet is a good writer and knows his stuff - plus he has one million stack overflow points worth of experience in explaining things.

epswing
Nov 4, 2003

Soiled Meat

ljw1004 posted:

??? Every mission-critical application is written with those same workarounds around that same issue.

I know you're right, I'm just still progressing through the denial phase. I guess I'm not used to having my application spread across multiple systems that can individually fail. It seems to fail an awful lot, for a web app that's not under any kind of serious load.

Here's the internal dialog:

Sometimes EF queries will fail due to transient errors
> No problem, just use SqlAzureExecutionStrategy to retry
Fine but now I can't use User Transactions
> Oh, just suspend the SqlAzureExecutionStrategy when you use User Transactions!
Sure but, aren't I back to square one?
> Well you can use this new connection resiliency feature for EF, just call SetTransactionHandler with CommitFailureHandler, which automatically creates a __Transactions table and inserts/removes rows to make sure transactions are committed properly.
Oh cool, so I can use User Transactions now?
> No User Transactions aren't supported

Ok. So wait, how do I wrap multiple calls to SaveChanges() into a single, bigger transaction? Or is that just off the table?

epswing fucked around with this message at 18:38 on Jan 13, 2017

epswing
Nov 4, 2003

Soiled Meat

john donne posted:

All of your production code should be wrapped in failure recovery in any case. Transient errors should not cause an application to fall over.

Do you have a favorite book, course, or article that teaches this kind of defensive programming (preferably with a .NET flavor)?

john donne
Apr 10, 2016

All suitors of all sorts themselves enthral;

So on his back lies this whale wantoning,

And in his gulf-like throat, sucks everything

That passeth near.
Unfortunately, I do not have any particular resources. Most engineers, I suspect, learn these habits after the first few times their whole site crashes because of a blip in a network connection (for example). Specifics around programming fault-tolerant systems are dependent on what kind of system you're building - is it an API integration? A concurrently-processing ETL built around a message bus? A microservice that's part of a larger web of interconnected services? A website? There are certainly resources and best-practices for each kind of system.

General guidelines are basically what ljw said: every time you make a network operation of any kind, wrap it in recovery code. If it's a database connection, you should be able to safely repeat data reads until it succeeds (while logging the failures and having some kind of eventual "escape" functionality so you don't get stuck in a loop) - with writes, a single row write is usually safe to repeat. Multiple rows need to be wrapped in transactions so you don't repeat writes that partially succeeded. You'll also need to be able to distinguish between transient problems or other failures from which you can recover, and failures which indicate a flawed data set or other issue that can't be resolved. And so on. But not all failures can be handled by simply re-trying the operation, so you'll need to treat each of those cases individually and come up with a strategy around how your application can recover... Or (this is typically a better approach), simplify your application's functionality until its reduced to operations that can be safely retried until they succeed. There are trade-offs to that, too, of course - which is why software engineering is a profession that demands creativity and technical skill. We will often face problems that cannot be solved with boilerplate libraries.

B-Nasty
May 25, 2005

The "Polly" library might be a good starting point for writing fault-tolerant code (https://github.com/App-vNext/Polly) You'll still need to think carefully about when and why you're doing the retry, but at least it should save you some boilerplate code.

Mr Shiny Pants
Nov 12, 2012

epalm posted:

I know you're right, I'm just still progressing through the denial phase. I guess I'm not used to having my application spread across multiple systems that can individually fail. It seems to fail an awful lot, for a web app that's not under any kind of serious load.

Here's the internal dialog:

Sometimes EF queries will fail due to transient errors
> No problem, just use SqlAzureExecutionStrategy to retry
Fine but now I can't use User Transactions
> Oh, just suspend the SqlAzureExecutionStrategy when you use User Transactions!
Sure but, aren't I back to square one?
> Well you can use this new connection resiliency feature for EF, just call SetTransactionHandler with CommitFailureHandler, which automatically creates a __Transactions table and inserts/removes rows to make sure transactions are committed properly.
Oh cool, so I can use User Transactions now?
> No User Transactions aren't supported

Ok. So wait, how do I wrap multiple calls to SaveChanges() into a single, bigger transaction? Or is that just off the table?

I can understand people saying you need to wrap this, on the other hand it seems like you are rebuilding functionality that is there but does not work right.

You wrap your code in a transaction block, but that does not seem to work. So now you have to write your own transaction layer. Where is the Value Add for EF in this instance?

Or am I reading this wrong?

Adbot
ADBOT LOVES YOU

EssOEss
Oct 23, 2006
128-bit approved
Transactions are not there to ensure things happen, they exist to synchronize different operations - so if money from account X is transferred to account Y, both account balances change. The failure handling layer above is for determining what to do when things go off the happy path. Completely orthogonal needs - you can do one without the other and mix them independently.

SqlAzureExecutionStrategy is a poor man's failure strategy, as it just retries the automatic transactions if it thinks the fault should clear itself. Yes, it is horribly limited. You will almost certainly want to use something better if what you are doing is not dead simple.

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