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
chippy
Aug 16, 2006

OK I DON'T GET IT
I would have done, but you've got a couple of good answers on there now.

Adbot
ADBOT LOVES YOU

Mezzanine
Aug 23, 2009

LOOK I AM A TURTLE posted:

Looks like you want something like this:

Thank you so much! One more question: suppose I want to call "WeatherConnection.GetWeather(43.0620960f, 141.3543760f);" from something that isn't async, like in a screen's "OnStart()" method or something similar. For example:
code:
public class MainActivity : Activity  
  protected override void OnStart ()
  {
    base.OnStart ();
    ShowProgressBar ();

    StartGetWeather(); // Is this ok?
  }

  async void StartGetWeather()
  {
      var weatherData = await WeatherConnection.GetWeather(43.0620960f, 141.3543760f);
  }
}
"OnStart()" gets called by the OS and does UI stuff. Normally, I would start the GetWeather process in another thread or something and give it a callback or listener for when it's done, which would then apply the data to the UI on the UI (main) thread. Should I make an "async void StartGetWeather()" method in my class and call it the same way you showed?

Mezzanine fucked around with this message at 01:29 on May 17, 2016

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Mezzanine posted:

Thank you so much! One more question: suppose I want to call "WeatherConnection.GetWeather(43.0620960f, 141.3543760f);" from something that isn't async, like in a screen's "OnStart()" method or something similar. For example:
code:
  
protected override void OnStart ()
{
  base.OnStart ();
  ShowProgressBar ();

  // HERE

}
"OnStart()" gets called by the OS and does UI stuff. Normally, I would start the GetWeather process in another thread or something and give it a callback or listener for when it's done, which would then apply the data to the UI on the UI (main) thread.

I'm about 99% sure you're using Xamarin.Forms. You can just add async to OnStart and then call that method. Although you probably don't want to, since that, if I recall correctly without looking at the docs, is called when the app starts using their native methods, and if that task hangs or takes too long to load, your program will crash.

You might want to invest some time looking to the many MVVM libraries that work with Forms, like Prism.

Mezzanine
Aug 23, 2009
Actually, I'm not using forms. I can't remember why, but I think it had something to do with trying to stay closer to the native implementation since I have enough experience with Android and iOS. I will definitely look at Prism, though!

Just going over the Xamarin Android documentation, it says something about using "ThreadPool.QueueUserWorkItem (o => SlowMethod ());" and "RunOnUiThread (() => DoThingWithTheUI());", so I'm gonna try that.

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.
Okay, this is baffling and if Google is any indication, has happened to literally nobody ever, so who wants a brainteaser?

I've got a WPF application that needs to read card swipes, which come in as keystrokes from the reader so it's pretty easy. In the application's constructor, I have this line:
code:
TextCompositionManager.AddPreviewTextInputStartHandler(this, new TextCompositionEventHandler(tcphandler));
Which leads to this function:
code:
public void tcphandler(object o, TextCompositionEventArgs e)
{
	e.Handled = true;
	cardbuffer += e.Text;
}
The e.Handled is there so the keystrokes don't go any further, and then I have OnKeyDown events to actually read the cardbuffer and decide when a card is finished being swiped. All of this works.

However, if you click anything on a page that takes any sort of interaction (buttons and textboxes are the two things I've found so far), the code stops working -- but only for the space bar. Every other keystroke still gets caught just fine, but space bar presses simply do not trigger tcphandler at all. I know they're going through because they trigger OnKeyDown just fine (and show up in the text box, because tcphandler isn't stopping them). There is absolutely zero code anywhere in the project regarding space bars being pressed.

Once you click away from the button or textbox, space bars still are not caught. However, loading a new page causes spaces to be properly handled again, until and unless you click a button or textbox, at which point they start failing to be caught again and can only be fixed by loading a new page.

CapnAndy fucked around with this message at 01:33 on May 18, 2016

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
I'm trying to implement an IAuthenticationFilter (the Web Api 2 flavour, NOT the MVC flavour) and I'm struggling with the order the code is executed. I would have expected the Authentication filter to be run before any controller-based stuff, so that I could set the appropriate principal and then load the relevant user data from my DbContext in some kind of base ApiController.

This is the flow I'm after:


AuthenticationFilter                    ==> BaseController                                     ==> Controller/Action
----------------------------------------==>----------------------------------------------------==>----------------------------------------------
Test Authorization header and set the   ==> Use the principal to find the full User record in  ==> Complete action as normal, has access to the
principal if all is well.               ==> database and assign it to protected property.      ==> user record as set in the BaseController



I'm not sure where to put the code in a BaseController in order to have it execute AFTER the authentication filter, but BEFORE the routed controller/action. Generally I find when I'm hitting a brick wall like this, it's because I'm trying to go the wrong way about something, so if any of the above sounds wrong let me know.

putin is a cunt fucked around with this message at 03:11 on May 18, 2016

Captain Melo
Mar 28, 2014
Is there an easy way to modify exif data on photos using C#? I don't know if I'm missing something obvious, but I'm completely coming up with a blank. I'm trying to edit the GPS information located in .jpeg files.

IcedPee
Jan 11, 2008

Yarrrr! I be here to plunder the fun outta me workplace! Avast!

FREE DECAHEDRON!
Does anyone have a link to a good article about how events propagate from a timer? I have this timer

code:

 public void StartTimer()
        {
            //Set timer for one second
            _timer = new Timer(1000);
            _timeLeft = 10;
            _timer.Elapsed += Timer_Elapsed;

            _timer.Start();

        }

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (_timeLeft >= 1 && !_stopTimer)
            {
                //Take it down and restart the one second timer
                _timeLeft--;
                
            }
            else
            {                
                _timer.Stop();
                OnTimerEnded(new EventArgs());
            }
        }

In addition, I've also got this event that could happen as a result from touch input

code:

 public override bool OnTouchEvent(MotionEvent e)
        {
            base.OnTouchEvent(e);
            if (e.Action == MotionEventActions.Down)
            {
                prevx = e.GetX();
                prevy = e.GetY();
            }
            if (e.Action == MotionEventActions.Move)
            {
                float e_x = e.GetX();
                float e_y = e.GetY();

                xdiff = (prevx - e_x);
                ydiff = (prevy - e_y);
                xangle = xangle + ydiff;
                yangle = yangle + xdiff;

                //add to the total distance
                totalDistance += Math.Abs(xdiff);
                totalDistance += Math.Abs(ydiff);

                if(totalDistance >= 400)
                {
                    totalDistance = 0;
                    ThingEvent?.Invoke(this, new ThingEventArgs());
                }

                prevx = e_x;
                prevy = e_y;
            }
            
            return true;
        }


protected virtual void OnThingEvent(object sender,ThingEventArgs e)
        {
            
            _stopTimer = true;
            
        }

Well, long story short, OnThingEvent fires predictably and sets _stopTimer to true, but Timer_Elapsed will continue to run and when the 10 seconds have counted down, _stopTimer is false. Nowhere else is _stopTimer accessed. I know this has to be a threading issue, I just wanted to know why this occurs and how to fix it.

IcedPee fucked around with this message at 05:00 on May 18, 2016

mortarr
Apr 28, 2005

frozen meat at high speed

Captain Melo posted:

Is there an easy way to modify exif data on photos using C#? I don't know if I'm missing something obvious, but I'm completely coming up with a blank. I'm trying to edit the GPS information located in .jpeg files.

https://github.com/mwijnands/JpegMetadata

Not sure if this deals with gps metadata, but it might be a starting point?

raminasi
Jan 25, 2005

a last drink with no ice

IcedPee posted:

Does anyone have a link to a good article about how events propagate from a timer? I have this timer

code:

 public void StartTimer()
        {
            //Set timer for one second
            _timer = new Timer(1000);
            _timeLeft = 10;
            _timer.Elapsed += Timer_Elapsed;

            _timer.Start();

        }

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (_timeLeft >= 1 && !_stopTimer)
            {
                //Take it down and restart the one second timer
                _timeLeft--;
                
            }
            else
            {                
                _timer.Stop();
                OnTimerEnded(new EventArgs());
            }
        }

In addition, I've also got this event that could happen as a result from touch input

code:

 public override bool OnTouchEvent(MotionEvent e)
        {
            base.OnTouchEvent(e);
            if (e.Action == MotionEventActions.Down)
            {
                prevx = e.GetX();
                prevy = e.GetY();
            }
            if (e.Action == MotionEventActions.Move)
            {
                float e_x = e.GetX();
                float e_y = e.GetY();

                xdiff = (prevx - e_x);
                ydiff = (prevy - e_y);
                xangle = xangle + ydiff;
                yangle = yangle + xdiff;

                //add to the total distance
                totalDistance += Math.Abs(xdiff);
                totalDistance += Math.Abs(ydiff);

                if(totalDistance >= 400)
                {
                    totalDistance = 0;
                    ThingEvent?.Invoke(this, new ThingEventArgs());
                }

                prevx = e_x;
                prevy = e_y;
            }
            
            return true;
        }


protected virtual void OnThingEvent(object sender,ThingEventArgs e)
        {
            
            _stopTimer = true;
            
        }

Well, long story short, OnThingEvent fires predictably and sets _stopTimer to true, but Timer_Elapsed will continue to run and when the 10 seconds have counted down, _stopTimer is false. Nowhere else is _stopTimer accessed. I know this has to be a threading issue, I just wanted to know why this occurs and how to fix it.

What happens if you declare _stoptimer volatile?

Night Shade
Jan 13, 2013

Old School

The Wizard of Poz posted:

I'm trying to implement an IAuthenticationFilter (the Web Api 2 flavour, NOT the MVC flavour) and I'm struggling with the order the code is executed. I would have expected the Authentication filter to be run before any controller-based stuff, so that I could set the appropriate principal and then load the relevant user data from my DbContext in some kind of base ApiController.

This is the flow I'm after:


AuthenticationFilter                    ==> BaseController                                     ==> Controller/Action
----------------------------------------==>----------------------------------------------------==>----------------------------------------------
Test Authorization header and set the   ==> Use the principal to find the full User record in  ==> Complete action as normal, has access to the
principal if all is well.               ==> database and assign it to protected property.      ==> user record as set in the BaseController



I'm not sure where to put the code in a BaseController in order to have it execute AFTER the authentication filter, but BEFORE the routed controller/action. Generally I find when I'm hitting a brick wall like this, it's because I'm trying to go the wrong way about something, so if any of the above sounds wrong let me know.

Honestly I'd just do something like:

code:
[MyAuthenticationFilter]
public class AuthenticatedUserController : HttpController 
{
  private readonly MyDbContext _context;
  private MyUser _user;
  public BaseController(MyDbContext context)
  {
    _context = context;
  }
  protected MyDbContext Context => _context;
  protected MyUser User => _user ?? (_user = _context.MyUsers.First(/* search goes here */));
}

public class SpecialisedController : AuthenticatedUserController
{
  public SpecialisedController(MyDbContext context) : base(context){}

  [HttpGet]
  public IEnumerable<MyResult> GetMyResult()
  {
    return Context.MyResults.Where(myResult => myResult.User.Id == User.Id);
  }
}

ljw1004
Jan 18, 2005

rum

mortarr posted:

https://github.com/mwijnands/JpegMetadata
Not sure if this deals with gps metadata, but it might be a starting point?

That code uses the .NET Framework class "System.Windows.Media.Imaging.JpegBitmapDecoder" to do its work, stored in "System.Windows.Media.Imaging.BitmapMetadata", which is certainly an easy route as requested :) There seems to be useful advice on how to use it to work with GPS tags here: http://www.codeproject.com/Questions/815338/Inserting-GPS-tags-into-jpeg-EXIF-metadata-using-n

Personally, I wrote some C# code which parses the JPEG/EXIF file format manually, and locates where exactly the timestamp and GPS coordinates are stored within the file. I use it to overwrite the timestamp with my own value. (It'd be straightforward to make it also overwrite the GPS coordinates in the same way). However, my approach is no good if you need to add GPS coordinates to an EXIF which doesn't already have them.
https://github.com/ljw1004/fix-camera-date/blob/master/FixCrossPlat/Program.cs

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.

IcedPee posted:

Does anyone have a link to a good article about how events propagate from a timer? I have this timer

code:

 public void StartTimer()
        {
            //Set timer for one second
            _timer = new Timer(1000);
            _timeLeft = 10;
            _timer.Elapsed += Timer_Elapsed;

            _timer.Start();

        }

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (_timeLeft >= 1 && !_stopTimer)
            {
                //Take it down and restart the one second timer
                _timeLeft--;
                
            }
            else
            {                
                _timer.Stop();
                OnTimerEnded(new EventArgs());
            }
        }

In addition, I've also got this event that could happen as a result from touch input

code:

 public override bool OnTouchEvent(MotionEvent e)
        {
            base.OnTouchEvent(e);
            if (e.Action == MotionEventActions.Down)
            {
                prevx = e.GetX();
                prevy = e.GetY();
            }
            if (e.Action == MotionEventActions.Move)
            {
                float e_x = e.GetX();
                float e_y = e.GetY();

                xdiff = (prevx - e_x);
                ydiff = (prevy - e_y);
                xangle = xangle + ydiff;
                yangle = yangle + xdiff;

                //add to the total distance
                totalDistance += Math.Abs(xdiff);
                totalDistance += Math.Abs(ydiff);

                if(totalDistance >= 400)
                {
                    totalDistance = 0;
                    ThingEvent?.Invoke(this, new ThingEventArgs());
                }

                prevx = e_x;
                prevy = e_y;
            }
            
            return true;
        }


protected virtual void OnThingEvent(object sender,ThingEventArgs e)
        {
            
            _stopTimer = true;
            
        }

Well, long story short, OnThingEvent fires predictably and sets _stopTimer to true, but Timer_Elapsed will continue to run and when the 10 seconds have counted down, _stopTimer is false. Nowhere else is _stopTimer accessed. I know this has to be a threading issue, I just wanted to know why this occurs and how to fix it.
I don't have an answer for you, but I have a way to get what you want. First off, you're doing Timer_Elapsed when you've got the definition of a ticking timer. Change it to:
code:
_timer = new Timer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += new EventHandler(_timer_Tick);
Now you can kill _stopTimer altogether, move the "decrement time left and stop timer if it's 0" logic to _timer_Tick, and just have OnThingEvent call _timer.Stop(), which will immediately stop the ticking. Easy peasy.

CapnAndy fucked around with this message at 17:28 on May 18, 2016

IcedPee
Jan 11, 2008

Yarrrr! I be here to plunder the fun outta me workplace! Avast!

FREE DECAHEDRON!

raminasi posted:

What happens if you declare _stoptimer volatile?

Functionally no different, sadly.


CapnAndy posted:

I don't have an answer for you, but I have a way to get what you want. First off, you're doing Timer_Elapsed when you've got the definition of a ticking timer. Change it to:
code:
_timer = new Timer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += new EventHandler(_timer_Tick);
Now you can kill _stopTimer altogether, move the "decrement time left and stop timer if it's 0" logic to _timer_Tick, and just have OnThingEvent call _timer.Stop(), which will immediately stop the ticking. Easy peasy.

Yeah, there's a reason I wasn't doing _timer.Tick - System.Timers.Timer doesn't have a Tick event. I actually create my own tick event and handle it elsewhere for UI stuff. Oddly enough, I have tried calling _timer.Stop() within OnThingEvent, but it doesn't stop the timer when I call it there just like _stopTimer is always reads false in the Timer_Elapsed handler even though I have set it to true in OnThingEvent. I was really hoping that marking _stopTimer as volatile was the solution.

I could try using a winforms timer, but this is a xamarin android application and I think there was a reason that would be bad. I don't recall what it is at the moment, so I'll give it a try.

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.

IcedPee posted:

Yeah, there's a reason I wasn't doing _timer.Tick - System.Timers.Timer doesn't have a Tick event. I actually create my own tick event and handle it elsewhere for UI stuff. Oddly enough, I have tried calling _timer.Stop() within OnThingEvent, but it doesn't stop the timer when I call it there just like _stopTimer is always reads false in the Timer_Elapsed handler even though I have set it to true in OnThingEvent. I was really hoping that marking _stopTimer as volatile was the solution.

I could try using a winforms timer, but this is a xamarin android application and I think there was a reason that would be bad. I don't recall what it is at the moment, so I'll give it a try.
Does Xamarin have System.Windows.Threading? Threading timers can tick.

If that's still impossible and the problem has to be solved, where do you declare _stopTimer to be false? You've got to be resetting it to false when the timer starts, but you didn't include that bit, or the bit where Timer_Elapsed actually restarts the timer. Without seeing them, I'm going to guess that what's happening is your timer restart method sets _stopTimer to false, and thus even though OnThingEvent sets it true, it gets overriden on the next "tick".

Can you just not call _timer.Stop() from OnThingEvent? I'm not sure if stopping counts as being elapsed, but I don't think it would. And if all of that stuff doesn't work, what about just setting _timeLeft to 0 and letting the regular logic stop itself?

IcedPee
Jan 11, 2008

Yarrrr! I be here to plunder the fun outta me workplace! Avast!

FREE DECAHEDRON!

CapnAndy posted:

Does Xamarin have System.Windows.Threading? Threading timers can tick.

If that's still impossible and the problem has to be solved, where do you declare _stopTimer to be false? You've got to be resetting it to false when the timer starts, but you didn't include that bit, or the bit where Timer_Elapsed actually restarts the timer. Without seeing them, I'm going to guess that what's happening is your timer restart method sets _stopTimer to false, and thus even though OnThingEvent sets it true, it gets overriden on the next "tick".

Can you just not call _timer.Stop() from OnThingEvent? I'm not sure if stopping counts as being elapsed, but I don't think it would. And if all of that stuff doesn't work, what about just setting _timeLeft to 0 and letting the regular logic stop itself?

Currently, I don't think I do set _stopTimer to false anywhere but when it's declared. My focus has been on getting the ThingEvent to successfully stop the timer before I worry about reset logic. StartTimer is called from a button press in the UI and is not used anywhere else in the application.

If setting _stopTimer to true in OnThingEvent handler doesn't change the value that's seen for _stopTimer in Timer_Elapsed, I have serious doubts that changing _timeLeft in the OnThingEvent handler will change the value that's seen for _timeLeft in Timer_Elapsed. I have definitely tried calling _timer.Stop() in OnThingEvent to no avail. This is what leads me to believe this is a threading problem.

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.

IcedPee posted:

Currently, I don't think I do set _stopTimer to false anywhere but when it's declared. My focus has been on getting the ThingEvent to successfully stop the timer before I worry about reset logic. StartTimer is called from a button press in the UI and is not used anywhere else in the application.

If setting _stopTimer to true in OnThingEvent handler doesn't change the value that's seen for _stopTimer in Timer_Elapsed, I have serious doubts that changing _timeLeft in the OnThingEvent handler will change the value that's seen for _timeLeft in Timer_Elapsed. I have definitely tried calling _timer.Stop() in OnThingEvent to no avail. This is what leads me to believe this is a threading problem.
I dunno, try it. The timer does time out after 10 seconds, right? You've tested that? Because this almost sounds like Xamarin is giving the timer variables of its very own when it's created.

IcedPee
Jan 11, 2008

Yarrrr! I be here to plunder the fun outta me workplace! Avast!

FREE DECAHEDRON!
Not surprisingly, setting _timeLeft to 0 in OnThingEvent does nothing to stop the timer.

The timer runs for 10 seconds and then stops, but no amount of outside influence (so far) seems to be able to stop it earlier than that. It definitely seems like the timer runs on a separate thread and that thread gets its own copies of _stopTimer and _timeLeft even though both are declared volatile.

System.Timers.Timer has a Disposed event where I can attach a handler, so maybe I can try forcing the issue from OnThingEvent that way.

Edit: assuming I can, you know, actually force the timer to dispose reliably.

IcedPee fucked around with this message at 19:45 on May 18, 2016

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.
My last idea is to declare them static instead of volatile.

IcedPee
Jan 11, 2008

Yarrrr! I be here to plunder the fun outta me workplace! Avast!

FREE DECAHEDRON!
Well, poo poo. From what I read on MSDN and Stack Overflow, the recommended fix is declare it volatile, but declaring it static volatile (not sure volatile is necessary) actually worked. Thanks, dude.

Baby Proof
May 16, 2009

How long does it typically take for a .NET version to go from Preview to Final? I'm running into a bug in 4.6.1 on my main development PC, and wondering whether to uninstall and drop back to 4.6, or install 4.6.2 preview from March 30th. I'm not doing anything remotely bleeding edge - I can go back to Visual Studio 2013 for a month or so if I need to.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Baby Proof posted:

How long does it typically take for a .NET version to go from Preview to Final? I'm running into a bug in 4.6.1 on my main development PC, and wondering whether to uninstall and drop back to 4.6, or install 4.6.2 preview from March 30th. I'm not doing anything remotely bleeding edge - I can go back to Visual Studio 2013 for a month or so if I need to.

Change the target framework to something else?

raminasi
Jan 25, 2005

a last drink with no ice

IcedPee posted:

Well, poo poo. From what I read on MSDN and Stack Overflow, the recommended fix is declare it volatile, but declaring it static volatile (not sure volatile is necessary) actually worked. Thanks, dude.

This really sounds like there's a deeper lifetime management problem in code you didn't post. (Or maybe it's just some dumb Xamarin thing, I don't know.)

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.

Baby Proof posted:

How long does it typically take for a .NET version to go from Preview to Final? I'm running into a bug in 4.6.1 on my main development PC, and wondering whether to uninstall and drop back to 4.6, or install 4.6.2 preview from March 30th. I'm not doing anything remotely bleeding edge - I can go back to Visual Studio 2013 for a month or so if I need to.

The version of visual studio you are using is unrelated to the version of the .NET runtime your code will be compiled against. You can choose to compile your project against any version of the runtime that you like.

Baby Proof
May 16, 2009

john donne posted:

The version of visual studio you are using is unrelated to the version of the .NET runtime your code will be compiled against. You can choose to compile your project against any version of the runtime that you like.

I wish it was that simple. The 4.6.1 install broke the compile for an old RIA Services / Silverlight (.NET 4.0) project. If I convert it to Open RIA Services or code a workaround, I'll have to track down old versions of 3rd party libraries and modify them too, so my only real options are to uninstall 4.6.1 or jump ahead to 4.6.2.

Munkeymon
Aug 14, 2003

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



I just basically copy-pasted the setup from https://github.com/nlog/NLog/wiki/Database-target into my NLog config but, when it tries to load it, it just throws with the error NLog.NLogConfigurationException: Required parameter 'CommandText' on 'Database Target[azure-sql]' was not specified

CommandText is definitely there... and also definitely flagged as invalid in VS with the message "This element cannot contain text. Content model is empty.", so I'm not sure what's right at this point. Any NLog users have any idea what the deal is?

Space Whale
Nov 6, 2014
I'm trying to troubleshoot a spike of InternalServerErrorExceptions that happened over an hour a few days ago to our API. The frustrating bit is that when you delve into the logs and the stack traces, ultimately all you get is "An unexpected error occurred", which is the most useless error message I can see, for the vast majority of cases. A few towards the end of the spike were caching related: "ERRCA0009" but none of the more senior devs here think that means anything at all.

All I know is that they came from the same referrer, they were related to the same thing, and if you look closely it just curves up like a standard bell curve then back down over the course of an hour.

Our logs have both the full requestURI and all of the headers in the request; POSTman hitting our production API returns valid results, so I can't recreate it. Stepping through a local version everything works fine, including "nothing found." The DB behind all of this is Mongo, and yes the API correctly handles "not found" from mongo.

Do vague reasons for "lol something is wrong" clustered in time like this indicate an error with connections, connection pools, hardware, the db - or is this just "poo poo happens!"

I've considered putting in some better error handling code but the response I get is "we could wrap everything in try/catch, what's your point?" and "just "timebox it" ". Not sure what to do except punt.

EDIT:
A caching server took a poo poo at the same time and everything lines up. Whee.

Space Whale fucked around with this message at 20:01 on May 19, 2016

ljw1004
Jan 18, 2005

rum

IcedPee posted:

Does anyone have a link to a good article about how events propagate from a timer? I have this timer
code:
 public void StartTimer()
        {
            //Set timer for one second
            _timer = new Timer(1000);
            _timeLeft = 10;
            _timer.Elapsed += Timer_Elapsed;

            _timer.Start();
        }
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (_timeLeft >= 1 && !_stopTimer)
            {
                //Take it down and restart the one second timer
                _timeLeft--;
                
            }
            else
            {                
                _timer.Stop();
                OnTimerEnded(new EventArgs());
            }
        }
Well, long story short, OnThingEvent fires predictably and sets _stopTimer to true, but Timer_Elapsed will continue to run and when the 10 seconds have counted down, _stopTimer is false. Nowhere else is _stopTimer accessed. I know this has to be a threading issue, I just wanted to know why this occurs and how to fix it.

The way to fix it is async/await. That will make your code simpler and, since you're only using the UI thread, all the threading issues will disappear. This is an instance of a general-purpose coding pattern "using async+await is easier than spaghetti events" and I made a short training video for it here. Here's how I'd write your code:

code:
public async Task StartTimerAsync()
{
  for (int timeLeft=0; timeLeft<10; timeLeft++)
  {
    await Task.Delay(1000);
    if (_stopTimer) break;
  }
  OnTimerEnded(new EventArgs());
}
I don't know what is your objective, but if you want the OnTimerEnded to be fired the instant that _stopTimer is set to true, then you'd make _stopTimer be a CancellationToken (which you pass as an argument to Task.Delay) rather than just a boolean that you poll once a second.


EDIT: I'd also dispense with "OnTimerEnded". You could instead just have someone await until StartTimerAsync() has ended.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Low-level fun stuff of the month: The standard's rules for variant interface calls are incomplete, have errors, are insane, and don't match .NET's behavior (which is even more insane).

Figure this one out:
code:
class A {}
class B : A {}
interface IVar<in T> { void P(T v); }
class S1
{
    public virtual void P(A v) { Console.WriteLine("A"); }
    public virtual void P(B v) { Console.WriteLine("B"); }
}
class S2 : S1, IVar<B>, IVar<A> {}
class S3 : S1, IVar<B> {}
class S4 : S3, IVar<B>, IVar<A> {}

void Test()
{
    ((IVar<B>)new S2()).P(null);    // Prints "B"
    ((IVar<B>)new S4()).P(null);    // Prints "A"
}

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
That is definitely screwy. Intuitively, I would expect it to print B twice, but I wouldn't be surprised if it printed A twice. However printing two different values is throwing me for a loop. I'd be interested to hear ljw1004's take on this.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Reordering the interfaces in S4 or the methods in S1 actually has no effect either.

I think the problem is that it has a fun piece of non-standard undocumented behavior: When matching the interface methods for a class, it only matches them if the interface is implementing the method for the first time, either because the class supplied a new implementation since the last time it implemented the interface (if ever). In other words, S4 has an implementation of IVar<A>.P(A), but doesn't have an implementation of IVar<B>.P(B) because that interface method was recycled. Since S4 is searched for matches before S3, it prefers the hit in S4.

This also means that 2 methods called from the same variant interface type could be implemented by 2 different interfaces on the class. :v:

OneEightHundred fucked around with this message at 02:07 on May 21, 2016

invision
Mar 2, 2009

I DIDN'T GET ENOUGH RAPE LAST TIME, MAY I HAVE SOME MORE?
Any of you guys done charts in C#? Got tasked to make a program that takes a CSV file as input and outputs scrollable/zoomable/pretty charts. Started off with 4 points of data every second over a 3 hour period and is now turning into 4 points of data every 1/10th of a second for 8 hours and I'm not real sure the current free library I'm using is going to be able to handle it.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

invision posted:

Any of you guys done charts in C#? Got tasked to make a program that takes a CSV file as input and outputs scrollable/zoomable/pretty charts. Started off with 4 points of data every second over a 3 hour period and is now turning into 4 points of data every 1/10th of a second for 8 hours and I'm not real sure the current free library I'm using is going to be able to handle it.

I haven't seen any charting libraries in the .NET world that don't suck or cost money. It's pretty easy to do charts and the like on the front-end using something like http://nvd3.org/.

Worst-case (e.g. static CSV file), you can write it as a self-hosted WebAPI app that just exposes the data as JSON for the front-end to consume. If you can get the data from an API somewhere, even better, you can do the whole thing in HTML/JS without involving C#.

amotea
Mar 23, 2008
Grimey Drawer
OxyPlot is alright, the docs suck though. They do have an interactive sample browser with loads of samples, but it was down last time I checked.

NihilCredo
Jun 6, 2011

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

invision posted:

Any of you guys done charts in C#? Got tasked to make a program that takes a CSV file as input and outputs scrollable/zoomable/pretty charts. Started off with 4 points of data every second over a 3 hour period and is now turning into 4 points of data every 1/10th of a second for 8 hours and I'm not real sure the current free library I'm using is going to be able to handle it.

XPlot is a F# wrapper around Google Charts and Plotly. You can use it from C# and embed it in WPF, or just output HTML/JS.

I would naively hope Google Charts to be able to handle a million data points - a very lazy googling suggests "[m]odern browsers can render up to 100.000 (or even a million) datapoints without problems. However, to keep rendering smooth on older browsers too, it is better to keep the number of datapoints below 10.000."

If you have an actual budget, I've used Infragistics in production and I was pretty happy with it, but I was doing network graphs rather than charts. You can get the trial version and see if it handles your data.

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

OneEightHundred posted:

Low-level fun stuff of the month: The standard's rules for variant interface calls are incomplete, have errors, are insane, and don't match .NET's behavior (which is even more insane).

Very strange. I can't wrap my head around what it ought to print, but clearly it ought to be the same for both cases. Try to bring this one to Eric Lippert's attention, if he isn't too busy with OCaml these days.

As a sidenote, this is why friends don't let friends design languages with both subtyping and parametric polymorphism.

ljw1004
Jan 18, 2005

rum

OneEightHundred posted:

Low-level fun stuff of the month: The standard's rules for variant interface calls are incomplete, have errors, are insane, and don't match .NET's behavior (which is even more insane).

Short story: I suspect this is a known bug relating to generic variance.

As you say, the CLR's algorithm for finding a match is it just walks through the interfaces in order until it finds the first match. That's why runtime behavior is sensitive to the exact order that interfaces are declared on a class.


Long story: I was a junior dev on the VB compiler team, just given "generic variance" as the first actual feature I'd own myself. It was a gnarly area so I tried to write a mathematical proof of my code's correctness -- but discovered the proof was impossible because of a defect in the ECMA spec. I presented it to the C# Language Design Meeting. We ruled out changing the ECMA spec (too hard) and CLR implementation (too costly). C# compiler decided to ignore the issue for being so minor, but I added some warnings into the VB compiler to alert you if you might run into it.



Punch line 1: I got invited to join the VB/C# language design team on the strength of this!

Punch line 2: It turned out that my VB warnings never delivered much value to users, but they had a bug in them that warned even on some legitimate real-world code that was fine. Eric Lippert was the one who implemented variance for C#, and he made the correct assessment that the warnings were too risky for too little value. That's the difference between a senior dev like him and a then junior one like me :)


PS. I'm not entirely sure it's the same bug because it takes a long time to walk through the exact behavior, and your example doesn't have a direct VB equivalent. Here's some more code to illustrate the issue:

code:
Interface I(Of Out T)
    Sub f()
End Interface

Class C
    Implements I(Of String)
    Implements I(Of Exception)
    ' VB's variance-warning-system warns about these two "diamond" interfaces

    Public Sub f_S() Implements I(Of String).f
        Console.WriteLine("S")
    End Sub

    Private Sub f_E() Implements I(Of Exception).f
        Console.WriteLine("E")
    End Sub
End Class

Module Module1
    Sub Main()
        Dim c = CType(New C(), I(Of Object))
        ' VB's variance-warning-system disallows an implicit cast to I(Of Object)

        c.f()
        ' This prints either "S" or "E" depending on which implements clause in "C" goes first
    End Sub
End Module
And ultimately, what can it really do? If there are two possible methods that can be invoked, should the CLR throw an "AmbiguousMethodException" at runtime at the moment of invocation? (that'd be a shame if the two methods end up behaving the same as is likely the case...)

ljw1004 fucked around with this message at 17:43 on May 21, 2016

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

ljw1004 posted:

As you say, the CLR's algorithm for finding a match is it just walks through the interfaces in order until it finds the first match. That's why runtime behavior is sensitive to the exact order that interfaces are declared on a class.
That's actually documented in the standard though, and the interface order is the same in both cases. I think this is a different thing.

I did some more tests and it reinforces that it considers the implementation of a method on an interface to be "no match" if the interface is a duplicate, but doesn't have a new implementation since the last time it was implemented. It's still a "new implementation" if the method is further up the class hierarchy, i.e.:

code:
class A {}
class B : A {}
class C : B {}
interface IVar<in T> { void P(T v); }
class S1
{
    public virtual void P(A v) { Console.WriteLine("A"); }
    public virtual void P(B v) { Console.WriteLine("B"); }
}
class S2 : S1, IVar<B> {}
class S3 : S2
{
    public new virtual void P(B v) { Console.WriteLine("B"); }
}
class S4 : S3, IVar<B>, IVar<A> {}

void Test()
{
    ((IVar<B>)new S4()).P(null);    // Prints "B"
}
... but I guess VB requires explicit implementations, so it doesn't do this. The problem is in the CLI though, not C#.

ljw1004 posted:

And ultimately, what can it really do? If there are two possible methods that can be invoked, should the CLR throw an "AmbiguousMethodException" at runtime at the moment of invocation? (that'd be a shame if the two methods end up behaving the same as is likely the case...)
Having to put up with ambiguity is unfortunate, but the whole process would have been a lot simpler if it came down to "find a matching interface, then call the method." The fact that it resolves on a per-method basis rather than per-type in the first place (which is how it's written in the standard) is bizarre.

It's also slow. There's no way to optimize interfaces to something like a static vtable where the variant types just map to those because there's no way to statically determine which interface will service a call to those "no match" slots.

OneEightHundred fucked around with this message at 21:14 on May 21, 2016

mystes
May 31, 2006

I'm trying to manipulate XPS files in C# like this but I'm having a really weird problem. The original VS project works fine for me, but I've tried to modify it so I can either run it from powershell or so I can run it as a console application and in both cases on the output from the file I'm testing it on, only the first page of the output file works in the XPS viewer, but I don't get any error messages.

Here is my last attempt to make it into a console application while modifying it as little as possible to try to figure out where the problem is (note the hardcoded paths partway down): http://pastebin.com/qmDik1b5

I've tried targeting different .net versions but even with .net 4.5 / x86 like in the demo program I can't get it to work. Am I missing something really obvious here?

Also it's really lame that there seems to be no sane way to modify XPS files. You can open them and read them using the not-quite-so-lovely WPF interface, but there isn't any way to copy content from them without messing around with XML (you can't just copy the child elements on each fixedpage because they reference other resources like fonts in the original archive). It seems like you should be able to be able to open XPS files and just change some stuff before saving it again, but it seems like you aren't actually able to do that.

It's frustrating because I was able to extract the text from an xps file in a few lines of powershell code, and it seemed like it would be just as easy to make some changes, but boy was I wrong.

Edit: Rather than modifying the XPS file, is there any other easy way to manipulate the content and then display it? I tried modifying the fixeddocument in memory and then passing it to a DocumentViewer control but that didn't really work either (it sort of worked sporadically, but I think that's unintended behavior); is there some way I can render a single fixedpage to a window at a time and then be able to modify it?

mystes fucked around with this message at 23:43 on May 21, 2016

Adbot
ADBOT LOVES YOU

mystes
May 31, 2006

mystes posted:

I'm trying to manipulate XPS files in C#
OK, to reply to my own post, after poking around more, the apis for XPS documents are really annoying but I figured out a simpler solution. Basically, the APIs are very much not intended to allow you to modify existing XPS files as WPF objects, which is a pity because it would be really simple if it worked, but you quickly run into the problem that if you read it back as actual FixedDocument objects you then can't really modify them as-is. If you try to stick them directly onto a visual or naiively serialize and then deserialize them it may sort of work, but there seem to be issues with glyphs sometimes, which I think may possibly be a result of the stupid font situation where all fonts must be embedded, but are typically subsetted/obfuscated (to deter copying). (The problem with the obfuscated fonts is that the obfuscation is based on the GUID in the filename, and while you can easily copy the font to another package, if you write glyphs to a new visual, when you turn it back into a fixeddocument windows will helpfully change the guid.) You would think you could easily just throw out the embedded font files and start over except that the XPS files don't even have the original font names so that may be hard or impossible.

All that said, I realized that while the approach of modifying the document as xml is unavoidable, it could be much simpler than the c# example I was looking at if rather than building a new package file, I simply *copied* the original XPS file and modified it in place. This avoids the need to copy the parts from one package to another.

Here is a simple example of turning all the text red in powershell:

code:
$oldfile = "$env:userprofile\documents\test2.xps"
$newfile = "$env:userprofile\documents\test2_out.xps"
cp $oldfile $newfile

$container = [System.IO.Packaging.Package]::Open($newfile, [System.IO.FileAccess]::ReadWrite)
$fixedpage_parts = $container.GetParts() | ? {$_.ContentType -eq "application/vnd.ms-package.xps-fixedpage+xml"}

$xmldoc = New-Object System.Xml.XmlDocument
$ns = New-Object System.Xml.XmlNamespaceManager($xmldoc.NameTable)
$ns.AddNamespace("xps", "http://schemas.microsoft.com/xps/2005/06")

foreach ($part in $fixedpage_parts) {
	$stream = $part.GetStream()
	$xmldoc.Load($stream)
	
	$xmldoc.SelectNodes("//xps:Glyphs",$ns) | % {$_.Fill = "#FFFF0000"}
	
	$stream.position = 0
	$xmldoc.Save($stream)
	$stream.SetLength($stream.Position)
}

$container.close()
The only problem with this approach is that if I want to add new text back to the document, even if I want to use a font in the original document, I think I can't necessarily assume that the font will have all the characters I need, so I'm back to needing to actually add stuff to the package. Adding images would also require adding them to the package. Otherwise, simply creating a new canvas in a visual with stuff I want to overlay and serializing it would probably be the easiest approach.

It would be so much easier if it was actually possible to render a fixedpage to a visual and then use the normal api for generating an XPS file again.

Edit: It turns out the font name is actually preserved in the obfuscated file (although you have to deobfuscate it, write out to the filesystem as a ttf file, and examine it to get at it). This makes me think that I might be able to switch back to the approach of adding the existing fixedpage to a visual, and then just cleaning it up a little bit.

mystes fucked around with this message at 17:09 on May 22, 2016

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