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
Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Bognar posted:

Unfortunately there's not an easily accessible C# REPL yet. You could use the F# interactive console in Visual Studio:


What? There's no need to use the F# console. This is basically what the Immediate Window is for, but you do have to be debugging.

Adbot
ADBOT LOVES YOU

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction
This is a sort-of .net question, but more of a xaml/winrt question. I have a Windows Phone 8.1 app, and I have a page with a listview using a wrapgrid for layout to display grid cells. I have a tap event hooked up in the item datatemplate, which triggers a frame navigation to another page. What I want to do is set up a page transition so that the effect achieved is similar to the Windows Phone start screen app-tap navigation, where the thing you tapped delays for a hundred milliseconds or so before sweeping away.

I looked at ContinuumNavigationTransitionInfo and CommonNavigationTransitionInfo (particularly whether IsStaggerElement would be the solution) and I cannot for the life of me figure out how to set this stuff up.

I also can't find any good tutorials and of course MSDN is terrible.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Ithaqua posted:

A note: It's generally a bad practice to subclass collections.
http://stackoverflow.com/questions/21692193/why-not-inherit-from-listt

Aside from the non-generic subclass, I'll give the benefit of the doubt to anyone subclassing ObservableCollections since the base class is so irritating. Who's using OC<T> and NOT subclassing it?

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction
This is ObservableCollection<T>:



Why is PropertyChanged protected, instead of public like CollectionChanged? What if I want to be notified when the Count property changes? As I currently want to, since I'm implementing ISupportIncrementalLoading. These questions are mostly rhetorical, I'm just once again irritated by OC<T>.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Mr. Crow posted:

Of all the reasons to hate OC<T> that seems like the silliest.

It's the inconsistency that's depressing. I was giving my example case to preemptively head off "but why would you ever want that" questions I sometimes get from Microsoft people when I try to build things with their broken APIs.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction
What's a good technique to parallelize a recursive, async retrieval task? Bear with my as I haven't fully thought this out. I'm loading hierarchical items (folders of items & folders) from a remote resource, and there's wait time associated with getting a folder's children. My current solution works perfectly fine... it's basically naively recursing folders. Looks something like this (substantially simplified):

code:
var allItems = new ObservableCollection<Item>();

async Task LoadStuff(Item folder) {
    var items = await folder.GetChildItems();
    this.allItems.Add(items);

    var folders = items.Where(item => item.IsFolder);
    foreach(var f in folders) {
        await LoadStuff(f);
    }
}

var rootFolder = ...
LoadStuff(rootFolder);
It's kinda slow. I'm trying to think of ways to make it faster. Doing something like "await Task.WhenAll(folders.Select(LoadStuff))" seems to balloon the number of threads in use, but I assume that's capped by thread pool availability anyway. I could potentially NOT modify allItems in the body and add an accumulator parameter to the method, then return the entire set at the end, but that's somewhat unfortunate because I am taking advantage of OC<T>'s events to do some progressive UI updates, but that may be manageable if there's a parallel technique here.

Maybe some kind of producer/consumer queue, capped with a particular degree of parallelism? Then push folders into it, get back children at some point in the future, evaluate them into more queue insertions? That's getting more complicated.

Factor Mystic fucked around with this message at 04:25 on Sep 5, 2014

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

ljw1004 posted:

"Balloon the number of threads" is a surprise to me. The await operator doesn't create new threads. Task.WhenAll doesn't create new threads. The general principle is that no keywords in C# create new threads, and only a few specific clearly-identified functions like "Task.Run" will allocate anything on the threadpool. So where did your mysterious ballooning threads come from? I don't know. There might have been other threads being used under the hood, due to misbehaved APIs, but it's hard to know without a debugger.

I don't know either. Perhaps I was misreading the my debug print statements, which also print the current Environment.CurrentManagedThreadId. Normally the highest id's I see are 7-8. With the WhenAll approach, the id's climbed steadily up into the 80's before I killed the process. I suppose my report could be inaccurate if the managed thread id doesn't reliably indicate which native thread is running and could tick higher even when reusing the same native thread at a later point, but poking around the reference source sure seems to imply that it's referring to a native thread.

ljw1004 posted:

Stepping back, let's examine the problem from a theoretical angle. By the time your algorithm completes you will have issued "N" total calls to the remote resource and they will have completed. No amount of parallelization will ever change this total number "N".

You believe that your remote resource can typically handle a higher rate of concurrent requests than just simply doing those N requests one after the other. This is a reasonable belief and true of most servers. So what is the optimum number of parallel requests? Impossible to say. We don't know if the server will be fielding requests from other clients at the same time. We don't know if the server will reject requests if it's busy, or queue them up. It's likely not a good use of resources to implement our own rate-adjusting throttling mechanism to determine on-the-fly the optimum number of requests (like the throttler in TCP/IP does).

This detailing of my situation is pretty accurate. I also do not know the optimum number of parallel requests, nor the behavior of the service when overloaded. It is undocumented, as far as I can tell. I suspect that the number of allowable requests is greater than 1, so some form of parallelization seemed to be plausible to reduce the total overall time.

ljw1004 posted:

The best practical answer, one that works great in most situations, is just pick a number. Let's say "3" parallel requests. If the server takes time "t" for each request, then you'll finish in about N*t/3.


Here are two idioms for throttling async stuff. The first looks stupid, but it's clear and works and doesn't need new abstractions and is robust, and that in my book is a good pattern :) If you run it all on the UI thread then you don't even need to worry about using concurrency-safe data structures. For instance, you can use a normal (non-concurrent) queue, and your ProcessWorkItem method can happily add things to an ObservableCollection that's databound to the UI.

code:
async void Button1_Click() {
    var t1 = WorkerAsync();
    var t2 = WorkerAsync();
    var t3 = WorkerAsync();
    await Task.WhenAll(t1,t2,t3);
}

async Task WorkerAsync() {
   while (queue.Count>0) {
      var i = queue.Dequeue();
      ProcessWorkItem(i);
   }
}
In your case, you described your problem recursively, but I've implemented it non-recursively. Just make a queue of all outstanding folders that have yet to be processed. In your "ProcessWorkItem" function, you can retrieve all child folders, add them to the queue, then retrieve all child files.

Yes, this seems like the most obvious approach, however I believe it'll be preferable to run queue consumption on another thread. (A detail which I left out of my example case is that this code is already running on a background Task thread, not on the UI thread. Since this is really more of a patterns question, it didn't seem super relevant. The reason is UI responsiveness. The OC<T> in my example is not databound in the UI. Not relevant details for a pattern question).

ljw1004 posted:

Here's another solution for throttling based on the "Dataflow" library from Microsoft. Dataflow is powerful and you can wire it up in more sophisticated ways. It runs the callbacks on the threadpool. But again, you're still turning the recursive thing into something queue-based.

code:
private static async Task LotsOfWorkAsync()
{
    ITargetBlock<Folder> throttle = null;
    throttle = Throttle<Folder>(
        async folder =>
        {
            // handle the folder by posting further folders to the throttle
        },
        maxParallelism: 3);
    throttle.Post(top_level_folder);

    // Signal that we're done enqueuing work.
    // Actually, I don't know where best to call this function.
    // You'd call it when there are no more items left to enqueue.
    // I don't know how to figure that out cleanly.
    //throttle.Complete();

    // Don't complete this async method until the queue is fully processed.
    await throttle.Completion;
}

private static ITargetBlock<T> Throttle<T>(Func<T, Task> worker, int maxParallelism)
{
    var block = new ActionBlock<T>(worker,
        new ExecutionDataflowBlockOptions {
            MaxDegreeOfParallelism = maxParallelism,
        });
    return block;
}

Thanks for the advice. It looks like a queue is the way to go in any case.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

ljw1004 posted:

I'm not sure which reference source you're looking at? The .NET reference source only says that the getter of CurretManagedThreadId is "extern". In any case, when you look at the debugger window, you usually see higher CurrentManagedThreadId than there are threads. This proves either that your way of testing isn't accurate or that the VS debugger fails to show all threads. I reckon the way of testing isn't accurate :)



Ok, fair enough... I acknowledge that eyeballing thread id's is not a reliable way of reporting the number of threads in use by a program.

I restored the WhenAll code from before, turned on the Threads window, and set a conditional breakpoint to break if the managed thread id >= 80. Now we can get a more accurate picture of what was actually happening when I said I thought the number of threads was ballooning



Ok I was a little off.

ljw1004 posted:

I reckon there's almost never a good reason to run your work on a background thread, and lots of bad reasons. Here are slides from a recent talk I gave to the Windows XAML team:






FACT: doing asynchronous work on the UI thread, i.e. using the await operator, will NEVER harm UI responsiveness, not even on the lowest-power device you'll find. The only things that harm responsiveness are when you have "10s" or "100s" concurrency (e.g. if you throttle up to 100 concurrent requests). Or when you have code which blocks a thread.

The only code that blocks a thread is (1) calling blocking APIs - in which case rewrite your code to use async APIs; or (2) doing a CPU-bound computational kernel - in which case do this small computational kernel inside Task.Run.

What you can end up with is an architecture where the orchestration of the app is done entirely on a single thread (i.e. all the awaiting, data-binding, app-logic, ...). And only the small computational inner-loops are done on the threadpool using Task.Run. This architecture will have fewer concurrency bugs and easier-to-read code.

I know who you are, and I appreciate you time replying. I also understand that what you're saying SHOULD be the case, and I SHOULDN'T need to run this op on a background thread to avoid UI glitchyness. And in fairness, the code has gone though several iterations and improvements from when I first noticed the issues, so to make sure I wasn't wasting everyone's time I went back and cloned the current background thread method (accepts a TaskCompletionSource so the UI-caller can await it anyway) to a normal "async Task<T>" method, and awaited it like normal. Glitchy. It's kind of hard to put meaning on behind that word... it's mostly related to touch latency, I suppose. As in, swiping pivot headers on a rhythm will be slower/unresponsive than when using the background thread approach.

I feel like there's an obvious explanation for this, and that is that it's not about the awaitables, it's that there's unexpectedly long blocking methods acting up here. I can't really nail it down (and this particular aspect of the program has already be "solved", so it's not a showstopper), but I do have two more data points:

1- Dynamic objects are involved. They're the actual response objects from my slow remote resource API. I'm plucking properties out of them into a normal statically typed class for the layer of the app we've been talking about.

2- The ui/touch latency is MUCH higher when using the WhenAll approach. To me this implies some kind of resource starvation scenario.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Jewel posted:

I've never used NuGet before but I think I did it..? https://www.nuget.org/packages/Betwixt/

Sorry if I did something horribly wrong with that, NuGet seems to have problems with providing both x86 and x64..? Should I have split them into separate packages?

Something goes wrong when I try to install it into a new project:

code:
PM> Install-Package Betwixt
Installing 'Betwixt 1.2.0'.
Successfully installed 'Betwixt 1.2.0'.
Adding 'Betwixt 1.2.0' to App2.Windows.
Uninstalling 'Betwixt 1.2.0'.
Successfully uninstalled 'Betwixt 1.2.0'.
Install failed. Rolling back...
Install-Package : Failed to add reference to 'Betwixt'. Please make sure that it is in the Global Assembly Cache.
At line:1 char:1
+ Install-Package Betwixt
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Install-Package], InvalidOperationException
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand
Also, I recommend adding a note about nuget to the github readme.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Jewel posted:

I have no idea what nuget wants from me, I've never personally used it and it's weird; can anyone help? :sigh:

Edit: I didn't realize I had License.txt in the lib folder accidentally, I only added it in 1.2 and I didn't see anyone complain before 1.2 but I don't know if that's because nobody told me it was wrong.

Try now..? It should be fixed in 1.3.3

Edit: I just split it up because nuget can't handle x64 and x86 assemblies so now you can use "Install_Package betwixt_x64" if you're targeting x64. I should be done for good now, no more updates. Sorry for anyone who downloaded each iteration, there were about three of you but I don't know if they were from here.

Cool, 1.3.3 installs.

Suggestion: your example in the github readme should be "new Tweener<float>" (missing the type param). Also, does it make sense to add some additional overloads to Update for other numeric types (eg, double?). Perhaps the time deltas you normally deal with are always floats and never doubles in which case carry on. Adding a double overload would mean I can just pass it "0.1" and not "0.1f", which is pretty minor all things considered.

I got this problem compiling a fresh project with your readme example:

quote:

There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "Betwixt", "x86".
This mismatch may cause runtime failures.
Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.

I had been targeting AnyCPU, so I switched it to x86. Then it threw a FileNotFoundException:

quote:

System.IO.FileNotFoundException: Could not load file or assembly 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.

File name: 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
at Betwixt.GenericMath.Subtract[T](T a, T b)
at Betwixt.Tweener`1.LerpFuncDefault(T start, T end, Single percent)
at Betwixt.Tweener`1.Calculate(T start, T end, Single percent, EaseFunc easeFunc, LerpFunc`1 lerpFunc)
at Betwixt.Tweener`1.Update(Single deltaTime)
at App2.MainPage..ctor()

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Jewel posted:

I think that's saying it can't load .Net 3.5..? Maybe you're on 2.0 or something? I'm usually in the gamedev department so I'm not used to these kind of problems, because usually my code isn't shared :sweatdrop:

And hmm, I should fix those. It'd require recompiling the documentation too so hopefully people aren't sick of my constant updates..! (I sure am)

It was a Universal App. I tried Betwixt on a desktop .NET 4.5 app and it worked fine*, but that leads me to another question: Any reason this can't be a PCL?

* = the code from your readme "settles" on 10.00488. I would've expected that a tweener with an end value of "10" would not actually end with a value greater than 10. Maybe during an elastic bounce or something, but not after it's finished. Without a lot of gamedev experience, I can't tell if this is normal or not.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction
My main project at work is a from scratch rewrite of an old, massive database application, and I'm doing it as an effective SPA with Ractive.js. Controllers are json API providers to the "real" backend. It's actually a rails app, but you were asking about the frontend. I like Ractive and the project is shaping up well.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

GrumpyDoctor posted:

Yeah, I thought of this too, but it's still a huge pain in the rear end compared to some hypothetical way to say "No, really, this changed, I promise you."

Heh, the default OC<T> claims another victim. Welcome brother.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

ljw1004 posted:

For .NET, it's going completely open source. The .NET team will do their development (checkins, bugs, ...) all in the open. If for whatever reason you wanted to package up your own tweaked version of System.Xml.dll with your app, say, you'll be able to do that.

Interesting. Time to think about a pull request for ObservableCollection<T>, perhaps.


ljw1004 posted:

For WPF, it has a solid roadmap for the future.

YAY! :hellyeah: And I see performance is an area of focus thank goodness. To be honest I'm much more excited about this WPF post than I am about .NET being open source.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

GrumpyDoctor posted:

While we're on the subject, is there some reason that the strategy of avoiding null-checking PropertyChanged via assigning a no-op delegate on construction hasn't gotten more traction? Is there some serious penalty to it that I'm unaware of?

It's minutely slower. I always initialize my events as "public event EventHandler OnButtz = delegate { };". Harder to get snagged on event related rough edges.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction
The discussion on the roslyn repo is really interesting, I recommend checking it out. I'm particularly interested in watching the discussion & work on destructible types and method contracts. Fascinating.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Drastic Actions posted:

Since we don't have a Windows Store specific thread, I'll guess I post this stuff here :shurg:. Microsoft talked a little bit about Windows 10 universal apps at MWC. Some of the Windows Phone APIs are going to be deprecated and made consistent with Windows itself. So DoSomethingAndContinue will be going away :woop:. It also seems like there will be more to have true cross-platform XAML support, with hopefully less conditional "#if WINDOWS_PHONE_APP" logic and more XAML solutions. They also showed off Xbox One Universal apps as well.

Gets me a bit amped for Build. Just months away from Awful Forums Reader on XB1 :getin:

Is there a source what what WP APIs are dead?

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

amotea posted:

I wish they'd just fix and improve WPF, and not reinvent the wheel over and over again. There is no viable alternative for desktop applications right now.

WPF is powerful enough for any UI stuff you can think of, it just needs some overhauling in some places.

Also, an updated cross-browser Silverlight would beat the hell out of the dumb Javascript hell everyone's using right now.

I also wish WPF would become less bad, so we agree on that point. However, you can take your xaml & data binding & mvvm principles and use them to build universal apps which are now much more integrated with the desktop.

And man you are behind the times wrt Silverlight. Browser plugins are dead, completely. Much better js runtimes & mobile killed it. It was a neat idea in its time but c'mon.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Calidus posted:

So am I missing anything?

  • Win10 runs iOS and Android with App-V

This isn't right, I think. App-V is for Win32/.NET app packaging for store listings. For ObjC & Android, it's native lang support in VS + implementing portions of those platform APIs using Universal Windows apis and then you recompile that project for Windows.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

ljw1004 posted:

PS. I'm due to give some Microsoft internal training talks on UWP app development in .NET, and the new CoreCLR and NuGet stuff. If you have further questions I'd love to hear them so I can incorporate the answers into my talks :). I'll make public versions of the talks too.

Here's a question: I don't understand how to target .NET Core in VS 2015. I had expected to see it in the framework dropdown on the 'New Project' screen, along with all the full .NET versions, but it's not there. I've googled but I don't know what the appropriate incantation is. This only shows command line tools. The 'More Frameworks' link doesn't say anything (and ps- the url implies I clicked this from 2013, but it was 2015).

Is this something that will only be possible after the 29th?

Factor Mystic fucked around with this message at 02:04 on Jul 26, 2015

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

ljw1004 posted:

Today in VS2015 you can do File>New>C#>Web>ConsoleApp/ClassLibrary. These are still in preview.

As of July 29th you'll be able to do File>New>C#/VB>Windows>Universal>App/ClassLibrary.

Those are all the project types which take advantage of .NETCore. (That means: these app types pick up one of the .NETCore implementations of the .NET runtime, and they pick up the .NETCore implementations of the .NET framework, and they deploy them app-locally.) .NETCore hasn't yet made its way into any other project types. I don't think we'll see it as an option for regular desktop apps (Console, WPF, WinForms) for a while. That's because these project types all depend upon the very large .NET framework that's part of the OS, and includes things like WPF and Winforms, things that aren't in .NETCore.

"File>New>C#>Web>ConsoleApp/ClassLibrary" doesn't show .NET Core in the New Project window, but I see I can switch over to it in project properties. That's a bit weird but I can deal.

Not sure why normal desktop Console apps couldn't target .NET Core the way a "web" Console app can.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Gul Banana posted:

it's due to legacy and IP
the 'full' non-core framework is required for WPF, forms, etc because they are implemented in terms of windows-specific APIs. directx is used heavily, stuff like system.drawing uses GDI, system.web uses http.sys, etc.

the new core is open source and cross-platform- they don't want to open source and can't make cross-platform parts of the older stuff. asp.net 5 runs purely on the OSS code and can use things like IIS optionally as plugins. windows 10-specific (uwp) stuff runs on .net core + proprietary windows specific parts. it can be thought of as a refactoring of WPF so that the xaml layer exists 'above' the .net one.

(although this is an oversimplification and not actually true. uwp is really more like 'WPF reimplemented in c++/COM, with the environments including .net able to access its apis via 'projection' plugins. for windows 8, the .net projection was a custom vertical; now it is .net core)

I know all that, perhaps you misinterpreted my statement. I'm not expecting that WPF or Winforms or a Full Desktop Console app be able to be targetted to .NET Core. I AM expecting that for certain project template types, I would be able to target .NET Core... for example, Console apps and Library (dll) projects as previously stated. This is part of where my confusion was, because even though "Web" Console/Library projects CAN target .NET Core, you CANNOT pick it from the "Framework" list in the New Project dialog. Furthermore, I'm not sure what differentiates a "Web" Console/Library project from a "Windows" Console/Library project except that the former can target .NET Core & the latter can't even though a "Web" Console/Library certainly will work on WIndows.

If I want to make a Console app that works on Windows and also works on Linux, and I want to build this thing in VS2015, currently I have to make a "Web" Console app targetted to Full .NET 4.6, then go into project properties and retarget it to .NET Core. This is confusing and irritating. Hence my question, why can't a "Windows" Console app retarget to .NET Core the way a "Web" Console app can. Is what's actually going on here a project file format selection? So if I go "Web" I get project.json and if I go "Windows" I get mything.csproj? And then what is changing on the 29th?

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction
.NET 4.6 Winforms question:

How do I disable DPI scaling for my app? (Or alternately stated, tell the system that my app is DPI aware and does not need to be auto scaled?)

Things I have tried:

  • The old way: call user32.dll's SetProcessDPIAware
  • The newer way: set dpiAware to true in app.manifest
  • The newest way: set EnableWindowsFormsHighDpiAutoResizing to true in App.config (both true and false tested because I can't tell if this is saying I am responsible for resizing or something in Winforms will auto resize things)

None of these work. Windows is still scaling my app on high DPI displays.

What does work is manually setting the application compatibility flag "Disable display scaling on high DPI settings". I feel like reaching into that location in the registry and fidding with that is not a great deployment story.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

ljw1004 posted:

If you're starting out development on a new app now, and if the sandbox limitations don't matter, you should be looking at UWP.

A couple questions on this

a) Is it possible to create a system tray icon? This is impossible in pure WPF.

b) Is it possible to make a UWP app look like a "normal" windows program? I guess what I'm asking about is like gdi common controls style. Everything in WPF looks weird (ie, not like an ancient windows program) because it rendered everything itself. I don't really view that as a plus. Not to mention the fuzzy rendering.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Factor Mystic posted:

.NET 4.6 Winforms question:

How do I disable DPI scaling for my app? (Or alternately stated, tell the system that my app is DPI aware and does not need to be auto scaled?)

Things I have tried:

  • The old way: call user32.dll's SetProcessDPIAware
  • The newer way: set dpiAware to true in app.manifest
  • The newest way: set EnableWindowsFormsHighDpiAutoResizing to true in App.config (both true and false tested because I can't tell if this is saying I am responsible for resizing or something in Winforms will auto resize things)

None of these work. Windows is still scaling my app on high DPI displays.

What does work is manually setting the application compatibility flag "Disable display scaling on high DPI settings". I feel like reaching into that location in the registry and fidding with that is not a great deployment story.

tunah posted:

Have you tried setting AutoScaleMode to "None" on the Form itself?

I forgot to say it, but yes, I tried that too. Nothing I have been able to do from within the app has managed to allow me to position the form in real coordinates.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

ljw1004 posted:

It's not possible for a UWP app to have a system-tray icon.
So Winforms still has a role to play. I still think Winforms is a good option for simple, small apps. Even the simplest UWP app is pretty complicated. You'd create a lot of value in the world if you could make it as dead simple as Winforms is.

ljw1004 posted:

Your UWP apps won't have fuzzy rendering. But they'll never end up looking like traditional "ancient" user32/gdi32 apps.

It's good that xaml rendering is no longer as busted, I guess. I know it makes me sound like a luddite, pining for GDI looking controls, but I hate that desktop apps now look like websites. Hate hate hate. I'd really rather just not build an app with that stack at all if that's what it's going to look like. On the other hand, maybe it's all in the design finesse. I like VS 2015 a lot, so if that's a xaml app then it's a strong vote of confidence for the architecture.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Munkeymon posted:

Then how has dotnetpad been doing it all this time? That guy used to follow this thread IIRC

https://github.com/Gobiner/DotNetPad/blob/master/Gobiner.DotNetPad.Runner/Program.cs#L30

Adbot
ADBOT LOVES YOU

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Inverness posted:

I'm keeping an eye on how the new code generator extensions for the compiler are progressing.

My main worry is that they're going to be limited by only allowing you to add new translation units during compilation for partial classes using the new 'replace' and 'original' syntax. AddTranslationUnit() is the only method offered and there is no setter for the Compilation property.

I see no reason why it should prevent you from replacing the Compilation instance entirely so existing syntax trees, references, or resources can be edited.

I realllllly don't like replace & original but I can't verbalize why clearly. Probably because it'll end up being used for more than machine generated code & it's too large an indirection to instantly grok.

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