public override int GetHashCode() { unchecked { return(CurrentCulture.GetHashCode() * CurrentUICulture.GetHashCode() * ManagedThreadId.GetHashCode() * Priority.GetHashCode() * ThreadName.GetHashCode() * ThreadState.GetHashCode() * IsBackground.GetHashCode() * IsThreadPoolThread.GetHashCode()); } }
/// <summary> /// Reduces application memory usage. /// </summary> /// <remarks> /// When the app enters the background, receives a memory limit changing /// event, or receives a memory usage increased event, it can /// can optionally unload cached data or even its view content in /// order to reduce memory usage and the chance of being suspended. /// This must be called from multiple event handlers because an application may already /// be in a high memory usage state when entering the background, or it /// may be in a low memory usage state with no need to unload resources yet /// and only enter a higher state later. /// </remarks> private void ReduceMemoryUsage() { var memUsage = MemoryManager.AppMemoryUsage; var removeUi = false; // If the app has caches or other memory it can free, it should do so now. // << App can release memory here >> // Additionally, if the application is currently // in background mode and still has a view with content // then the view can be released to save memory and // can be recreated again later when leaving the background. if (IsBackground && Window.Current != null && Window.Current.Content != null) { VisualTreeHelper.DisconnectChildrenRecursive(Window.Current.Content); // Clear the view content. Note that views should rely on // events like Page.Unloaded to further release resources. // Release event handlers in views since references can // prevent objects from being collected. Window.Current.Content = null; removeUi = true; } var shell = Window.Current?.Content as MainShell; shell?.RootFrame.Navigate(typeof(BlankPage)); // Clear the page cache if (shell?.RootFrame != null) { var cacheSize = shell.RootFrame.CacheSize; shell.RootFrame.CacheSize = 0; shell.RootFrame.CacheSize = cacheSize; } // Run the GC to collect released resources. GC.Collect(); var diffMemUsage = (memUsage - MemoryManager.AppMemoryUsage); TelemetryService.Current.TrackEvent("Memory Collection Completed", new Dictionary <string, string>() { { "cleaned_memory", diffMemUsage + "kb" }, { "is_background", IsBackground.ToString() }, { "remove_ui", removeUi.ToString() }, }); }
/// <summary> /// Create a list view item describing this HidEvent /// </summary> /// <returns></returns> public ListViewItem ToListViewItem() { string usageText = ""; string inputReport = null; foreach (ushort usage in Usages) { if (usageText != "") { //Add a separator usageText += ", "; } //Try to get a name for that usage string name = ""; if (Enum.IsDefined(typeof(Hid.UsagePage), UsagePage)) { UsagePage usagePage = (UsagePage)UsagePage; try { name = Enum.GetName(Utils.UsageType(usagePage), usage); } catch { } } if (name == null || name.Equals("") || Device.IsGamePad) //Gamepad buttons do not belong to Usage enumeration, they are just ordinal { name = usage.ToString("X2"); } usageText += name; } // Get input report for generic HID events if (IsGeneric) { inputReport = InputReportString(); } //If we are a gamepad display axis and dpad values if (Device != null && Device.IsGamePad) { //uint dpadUsageValue = GetUsageValue((ushort)Hid.UsagePage.GenericDesktopControls, (ushort)Hid.Usage.GenericDesktop.HatSwitch); //usageText = dpadUsageValue.ToString("X") + " (dpad), " + usageText; if (usageText != "") { //Add a separator usageText += " (Buttons)"; } if (usageText != "") { //Add a separator usageText += ", "; } usageText += GetDirectionPadState().ToString(); //For each axis foreach (KeyValuePair <HIDP_VALUE_CAPS, uint> entry in UsageValues) { if (entry.Key.IsRange) { continue; } //Get our usage type Type usageType = Utils.UsageType((UsagePage)entry.Key.UsagePage); if (usageType == null) { //Unknown usage type //TODO: check why this is happening on Logitech rumble gamepad 2. //Probably some of our axis are hiding in there. continue; } //Get the name of our axis string name = Enum.GetName(usageType, entry.Key.NotRange.Usage); if (usageText != "") { //Add a separator usageText += ", "; } usageText += entry.Value.ToString("X") + " (" + name + ")"; } } //Handle keyboard events else if (IsKeyboard) { //Get the virtual key System.Windows.Forms.Keys vKey = (Keys)RawInput.keyboard.VKey; usageText = vKey.ToString() + " -"; //Get the key flag if (IsButtonUp) { usageText += " UP"; } else if (IsButtonDown) { usageText += " DOWN"; } if (RawInput.keyboard.Flags.HasFlag(RawInputKeyFlags.RI_KEY_E0)) { usageText += " E0"; } if (RawInput.keyboard.Flags.HasFlag(RawInputKeyFlags.RI_KEY_E1)) { usageText += " E1"; } if (HasModifierShift) { usageText += " SHIFT"; } if (HasModifierControl) { usageText += " CTRL"; } if (HasModifierAlt) { usageText += " ALT"; } if (HasModifierWindows) { usageText += " WIN"; } //Put our scan code into our input report field inputReport = "0x" + RawInput.keyboard.MakeCode.ToString("X4"); } //Now create our list item ListViewItem item = new ListViewItem(new[] { usageText, inputReport, UsagePageNameAndValue(), UsageCollectionNameAndValue(), RepeatCount.ToString(), Time.ToString("HH:mm:ss:fff"), IsBackground.ToString() }); return(item); }