Monday, November 29, 2021

How to prevent messy desktop when the monitor switches off

A problem that bothered me for a couple of days when I moved on to another worsktation with Windows 10: when you leave your desktop unattended for the power saving to kick in and turn off your monitor - the desktop would go crazy : all windows will be moved and resize as if to fit into a very small desktop size.
After some googling it turned out that Windows would "lose" the identification of the connected monitor and would switch to another "default" monitor. And will change the layout of the desktop to the size of this "default" monitor. Which turns out to be 1024x768.

In order to change that the following steps need to be taken:
  • Open RegEdit
  • Go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration
  • Find the "default" device.
  • This part is a bit tricky. I first deleted all the keys that were there besides something that looked to me like my SAMSUNG monitor description.
  • Then when my monitor went to sleep again Windows added another key to the registery with the name of NOEDID_8086_9BC5_00000000_00020000_31063...
  • This is the key under which some settings need to be changed:
  • et voila

    Monday, November 22, 2021

    A tiny and very handy CachedValue class

    In server-side programming it happens very often that getting a value takes a lot of time, but the result can be stored for some time. A classical answer to this is of course caching. The class below allows to wrap this in a very simple model.
    
    using System;
    
    namespace IBSoft.Helpers
    {
        public class CachedValue<T>
        {
            private T        value;
            private double   ttlInSeconds;
            private Func<T>  getValue;
            private DateTime expireAt = DateTime.MinValue;
    
            public CachedValue(int ttlInSeconds, Func<T> getValue)
            {
                this.ttlInSeconds = ttlInSeconds;
                this.getValue = getValue;
            }
    
            public T Value
            {
                get
                {
                    if (DateTime.UtcNow > this.expireAt)
                    {
                        T oldValue = this.value;
    
                        this.value = getValue();
    
                        var now = DateTime.UtcNow;
                        this.expireAt = now.AddSeconds(ttlInSeconds);
    
                        if (!this.value.Equals(oldValue))
                            this.LastValueUpdate = now;
                    }
    
                    return this.value;
                }
            }
    
            /// <summary>
            /// set when the value changes
            /// </summary>
            public DateTime LastValueUpdate { get; private set; }
    
            /// <summary>
            /// invalidates the value and causes reload on the next call
            /// </summary>
            public void Invalidate()
            {
                this.expireAt = DateTime.MinValue;
            }
    
            /// <summary>
            /// add implicit type conversion to T so that it's possible to use CacheValue<T> without the need to do cv.Value
            /// </summary>
            /// <param name="cv"></param>
            /// <returns></returns>
            public static implicit operator T(CachedValue<T> cv)
            {
                return cv.Value;
            }
        }
    }