├── .gitignore ├── AddingNumbersInParallel ├── AddingNumbersInParallel.csproj └── Program.cs ├── Benchmarks ├── Benchmarks.csproj ├── Memory │ ├── StringBuilderFewStrings.cs │ └── StringBuilderManyStrings.cs ├── Program.cs └── Serializers │ ├── DeserializeFromString.cs │ ├── Models.cs │ ├── RequestPerSecondClient.cs │ ├── SerializeSmallClass.cs │ ├── SerializeToStream.cs │ ├── SerializeToString.cs │ └── benchmark_results.md ├── BenchmarksServerDotNetCore3 ├── BenchmarksServerDotNetCore3.csproj ├── Controllers │ ├── HomeController.cs │ └── JsonSerializeController.cs ├── Formatters │ ├── JilFormatter.cs │ └── Utf8JsonFormatter.cs ├── Models │ └── ErrorViewModel.cs ├── Program.cs ├── Startup.cs ├── Views │ ├── Home │ │ ├── Index.cshtml │ │ └── Privacy.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── Calculator ├── App.config ├── Calculator.csproj ├── CalculatorEngine.cs ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── PracticalDebuggingWeb ├── .config │ └── dotnet-tools.json ├── Controllers │ ├── HomeController.cs │ ├── PriceCalculatorController.cs │ └── Services │ │ ├── CouponService.cs │ │ ├── Currency.cs │ │ ├── CurrencyConverter.cs │ │ ├── CurrencyService.cs │ │ └── PriceCalculator.cs ├── Models │ └── ErrorViewModel.cs ├── PracticalDebuggingWeb.csproj ├── Program.cs ├── Startup.cs ├── Views │ ├── Home │ │ ├── Crash.cshtml │ │ ├── Index.cshtml │ │ ├── Privacy.cshtml │ │ └── SignIn.cshtml │ ├── PriceCalculator │ │ └── Result.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _CookieConsentPartial.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json ├── web.config └── wwwroot │ ├── css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── PracticalDebugingDemos.sln ├── PracticalDebugingDemos ├── App.config ├── App.xaml ├── App.xaml.cs ├── DemoBase.cs ├── Demos │ ├── Crashes │ │ ├── SimpleCrash.cs │ │ └── Tools │ │ │ ├── DebugWriteLine.cs │ │ │ └── TraceWriteLine.cs │ ├── Debug3rdPartyCode │ │ ├── NewtonsoftDeserialize.cs │ │ └── NewtonsoftSerialize.cs │ ├── Dumps │ │ └── FirstChanceException.cs │ ├── Files │ │ └── ReadOneFile.cs │ ├── Freezes │ │ ├── BeginInvokeFreeze.cs │ │ ├── CpuBoundFreeze.cs │ │ ├── DispatcherQueueDeadlock.cs │ │ ├── DotResultDeadlock.cs │ │ ├── DoubleNetstedDeadlock.cs │ │ ├── IOBoundFreeze.cs │ │ ├── OddEven │ │ │ ├── OddEvenCounter.cs │ │ │ ├── OddEvenMenu.xaml │ │ │ └── OddEvenMenu.xaml.cs │ │ └── OddEvenFreeze.cs │ ├── Memory │ │ ├── EndlessMemory.cs │ │ ├── EndlessMemory2.cs │ │ ├── ManyAllocationsGCPressureGen0Pressure.cs │ │ ├── ManyAllocationsGCPressureGen1Pressure.cs │ │ ├── MemoryExceeds2GB.cs │ │ ├── StockMarketMemoryLeak.cs │ │ ├── StockMarketWindow.xaml │ │ ├── StockMarketWindow.xaml.cs │ │ ├── StringBuilderFewStrings.cs │ │ ├── StringBuilderOutOfMemory.cs │ │ └── TimerMemoryLeak.cs │ ├── Misc │ │ └── Break.cs │ ├── Models │ │ └── Person.cs │ ├── Performance │ │ ├── AddInParallel.cs │ │ ├── CountPrimes.cs │ │ ├── LongAsyncNetworkRequest.cs │ │ ├── LongSynchronousFileRead.cs │ │ ├── LongSynchronousNetworkRequest.cs │ │ ├── ManyExceptions.cs │ │ ├── Sorting.cs │ │ ├── Sorting │ │ │ ├── Bubble.cs │ │ │ ├── ISortingStrategy.cs │ │ │ ├── QuickSort.cs │ │ │ ├── SortingMenu.xaml │ │ │ └── SortingMenu.xaml.cs │ │ ├── ThreadsWaiting.cs │ │ └── ThreadsWaitingAutoResetEvent.cs │ ├── PerformanceCountersConsume │ │ └── PerformanceCountersConsume.cs │ ├── PerformanceCountersThreeCpuThreads │ │ └── PerformanceCountersThreeCPUThreads.cs │ └── VisualStudio │ │ ├── MultiThreadedCounter.cs │ │ └── ParallelWatchExample.cs ├── MainViewModel.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── PracticalDebuggingDemos.csproj ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ └── wrench.ico ├── lib │ └── Newtonsoft.Json.dll ├── packages.config └── wrench.ico ├── SortingStrategies ├── Bubble.cs ├── MergeSort.cs ├── Program.cs ├── QuickSort.cs ├── Sorter.cs └── SortingStrategies.csproj └── VideoSlides ├── 12-WinDbg introduction └── 22-windbg.pptx ├── 13-PerfView introduction └── 23-perfview.pptx ├── 14-EventViewer └── 24.pptx ├── 15-ProcessExplorer └── 25.pptx ├── 17-ILSpy └── 17.pptx ├── 18-Fiddler └── 18.pptx ├── 19-OzCode └── 19.pptx ├── 31-VSBasics └── 31.pptx ├── 32-VSToolWindows └── 32.pptx ├── 33-DebugCatchExceptions └── 33.pptx ├── 41-ProcDumpAndDebugInVS └── 41.pptx ├── 42-DumpWithWinDbg └── 42.pptx ├── 51-OpenCrashInVisualStudio └── 51.pptx ├── 61-DebugHangsInVisualStudio └── 61.pptx ├── 62-DebugHangsInDotTrace └── 62.pptx ├── 71-MemprofilerIntro └── 71.pptx ├── 72-MemoryLeakFindWithDotTrace └── 72.pptx ├── 73-MemoryLeakInVisualStudio └── 73.pptx ├── 81-PerformanceProfileDotTrace └── 81.pptx ├── 82-PerformanceProfilePerfView └── 82.pptx ├── 91-dotTraceAndDnSpy └── 91.pptx └── 92-debugInVisualStudio └── 92.pptx /AddingNumbersInParallel/AddingNumbersInParallel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.0 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AddingNumbersInParallel/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace AddingNumbersInParallel 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Console.WriteLine("Enter how many random numbers to add"); 13 | var items = int.Parse(Console.ReadLine()); 14 | var numbers = GetRandomNumbers(items); 15 | var sum = Sum(numbers); 16 | Console.WriteLine($"Sum = {sum}"); 17 | Console.WriteLine("Finished"); 18 | } 19 | 20 | private static object _lock = new object(); 21 | 22 | 23 | public static int[] GetRandomNumbers(int items) 24 | { 25 | int[] res = new int[items]; 26 | var rnd = new Random(); 27 | for (int i = 0; i < items; i++) 28 | { 29 | res[i] = rnd.Next(100); 30 | } 31 | 32 | return res; 33 | } 34 | 35 | public static int Sum(int[] arr) 36 | { 37 | int items = arr.Length; 38 | int total = 0; 39 | int threads = Math.Min(items, 8); 40 | var partSize = Math.Round(items / (double)threads + 0.5); 41 | Task[] tasks = new Task[threads]; 42 | for (int iThread = 0; iThread < threads; iThread++) 43 | { 44 | var localThread = iThread; 45 | tasks[localThread] = Task.Run(() => 46 | { 47 | var to = Math.Min(items, Math.Round((localThread + 1) * partSize + 0.5)); 48 | for (int j = (int)(localThread * partSize); j < to; j++) 49 | { 50 | lock (_lock) 51 | { 52 | total += arr[j]; 53 | } 54 | } 55 | }); 56 | } 57 | 58 | Task.WaitAll(tasks); 59 | //var verifySum = arr.Sum(); 60 | return total; 61 | } 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Benchmarks/Benchmarks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp3.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Benchmarks/Memory/StringBuilderFewStrings.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using System.Text; 3 | 4 | namespace Benchmarks.Memory 5 | { 6 | public class StringBuilderFewStrings 7 | { 8 | public static string A = "asdf"; 9 | public static string B = "ghjkl"; 10 | public static string C = ";lkjqwer"; 11 | public static string D = "zx"; 12 | 13 | 14 | [Benchmark] 15 | public string ExecuteA() 16 | { 17 | return A + B + C + D; 18 | } 19 | 20 | [Benchmark] 21 | public string ExecuteB() 22 | { 23 | StringBuilder sb = new StringBuilder(A); 24 | sb.Append(B); 25 | sb.Append(C); 26 | sb.Append(D); 27 | return sb.ToString(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Benchmarks/Memory/StringBuilderManyStrings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using BenchmarkDotNet.Attributes; 7 | 8 | namespace Benchmarks.Memory 9 | { 10 | public class StringBuilderManyStrings 11 | { 12 | [Benchmark] 13 | public string RegularConcatenation() 14 | { 15 | string s = ""; 16 | for (int i = 0; i < 1000; i++) 17 | { 18 | s += "a"; 19 | } 20 | 21 | return s; 22 | } 23 | 24 | [Benchmark] 25 | public string StringBuilder() 26 | { 27 | StringBuilder sb = new StringBuilder(); 28 | for (int i = 0; i < 1000; i++) 29 | { 30 | sb.Append("a"); 31 | } 32 | 33 | return sb.ToString(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Benchmarks/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using BenchmarkDotNet.Running; 5 | using Benchmarks.Memory; 6 | using Benchmarks.Serializers; 7 | 8 | namespace Benchmarks 9 | { 10 | class Program 11 | { 12 | static async Task Main(string[] args) 13 | { 14 | //BenchmarkRunner.Run(); 15 | //BenchmarkRunner.Run(); 16 | //BenchmarkRunner.Run(); 17 | //BenchmarkRunner.Run>(); 18 | //BenchmarkRunner.Run>(); 19 | //BenchmarkRunner.Run>(); 20 | //BenchmarkRunner.Run>(); 21 | await new RequestPerSecondClient().Run(false, false); 22 | 23 | //var x = new SerializeToStream(); 24 | //x.Setup(); 25 | //x.RunSystemTextJson(); 26 | //var memoryStream = x.GetMemoryStream(); 27 | //x.GetStreamWriter().Flush(); 28 | 29 | //memoryStream.Position = 0; 30 | //using var sr = new StreamReader(memoryStream); 31 | //var res = sr.ReadToEnd(); 32 | //Console.WriteLine(res); 33 | 34 | 35 | //var x = new SerializeToString(); 36 | //x.Setup(); 37 | //var s1 = x.RunSystemTextJson(); 38 | //var s2 = x.RunNewtonsoft(); 39 | //var s3 = x.RunDataContractJsonSerializer(); //with UTC 40 | //var s4 = x.RunJil(); 41 | //var s5 = x.RunUtf8Json(); //same output as newtonsoft 42 | //var s6 = x.RunServiceStack();// with wrong UTC 0000 43 | 44 | //var x = new DeserializeFromString(); 45 | //x.ServiceStackSetup(); 46 | //var y = x.RunServiceStack(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Benchmarks/Serializers/DeserializeFromString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.Serialization; 4 | using System.Runtime.Serialization.Json; 5 | using System.Text.Json.Serialization; 6 | using BenchmarkDotNet.Attributes; 7 | using Newtonsoft.Json; 8 | using JsonSerializer = System.Text.Json.JsonSerializer; 9 | using SST = ServiceStack.Text; 10 | 11 | namespace Benchmarks.Serializers 12 | { 13 | public class DeserializeFromString where T : class, new() 14 | { 15 | 16 | private T _instance; 17 | private string _json; 18 | private DataContractJsonSerializer _dataContractJsonSerializer; 19 | private SerializeToString _serializer; 20 | 21 | public void Setup() 22 | { 23 | _serializer = new SerializeToString(); 24 | _serializer.Setup(); 25 | _instance = new T(); 26 | _dataContractJsonSerializer = new DataContractJsonSerializer(typeof(T)); 27 | } 28 | 29 | 30 | [GlobalSetup(Target = nameof(SystemTextJson))] 31 | public void SystemTextJsonSetup() 32 | { 33 | Setup(); 34 | _json = _serializer.RunSystemTextJson(); 35 | } 36 | [Benchmark] 37 | public T SystemTextJson() 38 | { 39 | return JsonSerializer.Deserialize(_json); 40 | } 41 | 42 | [GlobalSetup(Target = nameof(RunNewtonsoft))] 43 | public void NewtonsoftSetup() 44 | { 45 | Setup(); 46 | _json = _serializer.RunNewtonsoft(); 47 | } 48 | [Benchmark] 49 | public T RunNewtonsoft() 50 | { 51 | return JsonConvert.DeserializeObject(_json); 52 | } 53 | 54 | 55 | [GlobalSetup(Target = nameof(RunJil))] 56 | public void JilSetup() 57 | { 58 | Setup(); 59 | _json = _serializer.RunJil(); 60 | } 61 | [Benchmark] 62 | public T RunJil() 63 | { 64 | return Jil.JSON.Deserialize(_json); 65 | } 66 | 67 | [GlobalSetup(Target = nameof(RunUtf8Json))] 68 | public void Utf8JsonSetup() 69 | { 70 | Setup(); 71 | _json = _serializer.RunUtf8Json(); 72 | } 73 | [Benchmark] 74 | public T RunUtf8Json() 75 | { 76 | return Utf8Json.JsonSerializer.Deserialize(_json); 77 | } 78 | 79 | [GlobalSetup(Target = nameof(RunServiceStack))] 80 | public void ServiceStackSetup() 81 | { 82 | Setup(); 83 | _json = _serializer.RunServiceStack(); 84 | } 85 | [Benchmark] 86 | public T RunServiceStack() 87 | { 88 | return SST.JsonSerializer.DeserializeFromString(_json); 89 | } 90 | 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Benchmarks/Serializers/Models.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Benchmarks.Serializers 9 | { 10 | public class Models 11 | { 12 | private const int ITEMS = 1000; 13 | public class ThousandSmallClassList 14 | { 15 | public List List { get; set; } 16 | public ThousandSmallClassList() 17 | { 18 | List = new List(Enumerable.Range(0,ITEMS).Select(x => new SmallClass())); 19 | } 20 | } 21 | 22 | public class ThousandSmallClassArray 23 | { 24 | public SmallClass[] Arr { get; set; } 25 | public ThousandSmallClassArray() 26 | { 27 | Arr = new List(Enumerable.Range(0,ITEMS).Select(x => new SmallClass())).ToArray(); 28 | } 29 | } 30 | 31 | public class ThousandSmallClassDictionary 32 | { 33 | public Dictionary Dict { get; set; } 34 | public ThousandSmallClassDictionary() 35 | { 36 | Dict = new Dictionary(Enumerable.Range(0, ITEMS) 37 | .Select(x => new { Num = x, Obj = new SmallClass()}) 38 | .Select(anon => new KeyValuePair(anon.Obj.Name + anon.Num.ToString(), anon.Obj))); 39 | } 40 | } 41 | 42 | public class SmallClass 43 | { 44 | [DataMember] 45 | public string Name { get; set; } 46 | [DataMember] 47 | public int NumPurchases { get; set; } 48 | [DataMember] 49 | public bool IsVIP { get; set; } 50 | 51 | public SmallClass() 52 | { 53 | Name = "Bill Gates"; 54 | NumPurchases = 1200; 55 | IsVIP = true; 56 | } 57 | } 58 | 59 | // BigClass 60 | public class BigClass 61 | { 62 | public BigClass() 63 | { 64 | Id = 1; 65 | ClubMembershipType = ClubMembershipTypes.Platinum; 66 | Gender = Gender.Female; 67 | FirstName = "Louise"; 68 | MiddleInitial = "C"; 69 | Surname = "Midgett"; 70 | Address = new Address 71 | { 72 | StreetAddress = "43 Compare Valley", 73 | City = "Chambersburg", 74 | State = "PA", 75 | ZipCode = 17201, 76 | Country = "US" 77 | }; 78 | EmailAddress = "LouiseCMidgett@dodgit.com"; 79 | TelephoneNumber = "717-261-7855"; 80 | MothersMaiden = "Kelly"; 81 | NextBirthday = Convert.ToDateTime("1-May-84"); 82 | CCType = "Visa"; 83 | CaseFileID = "192-80-6448"; 84 | UPS = "1Z W64 924 70 0191 812 7"; 85 | Occupation = "Traffic technician"; 86 | Domain = "ScottsdaleSkincare.com"; 87 | MembershipLevel = "A+"; 88 | Kilograms = "64.2"; 89 | } 90 | 91 | public string FullName { get; set; } 92 | 93 | public int Id { get; set; } 94 | public Gender Gender { get; set; } 95 | public string FirstName { get; set; } 96 | public string MiddleInitial { get; set; } 97 | public string Surname { get; set; } 98 | public string EmailAddress { get; set; } 99 | public string TelephoneNumber { get; set; } 100 | public string MothersMaiden { get; set; } 101 | 102 | public DateTime NextBirthday { get; set; } 103 | public string CCType { get; set; } 104 | public string CaseFileID { get; set; } 105 | public string UPS { get; set; } 106 | public string Occupation { get; set; } 107 | public string Domain { get; set; } 108 | public string MembershipLevel { get; set; } 109 | public string Kilograms { get; set; } 110 | 111 | private int _pendingInvoiceID; 112 | 113 | 114 | public int PendingInvoiceID 115 | { 116 | get { return _pendingInvoiceID; } 117 | set { _pendingInvoiceID = value; } 118 | } 119 | 120 | public Address Address { get; set; } 121 | public ClubMembershipTypes ClubMembershipType { get; set; } 122 | public int YearsAsCustomer { get { return 5; } } 123 | 124 | public double GetYearlyEarnings(int year) 125 | { 126 | return year * 2; 127 | } 128 | 129 | internal int GetTotalMoneySpentAtStoreInUSD() 130 | { 131 | return ((int)FirstName[0])*50; 132 | } 133 | } 134 | 135 | public enum Gender 136 | { 137 | Male, Female 138 | } 139 | 140 | public enum ClubMembershipTypes 141 | { 142 | Premium, Platinum 143 | } 144 | 145 | public class Address 146 | { 147 | public string StreetAddress { get; set; } 148 | public string City { get; set; } 149 | public string State { get; set; } 150 | public int ZipCode { get; set; } 151 | public string Country { get; set; } 152 | } 153 | // -- end of BigClass 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /Benchmarks/Serializers/RequestPerSecondClient.cs: -------------------------------------------------------------------------------- 1 | //#define UTF8JSON 2 | //#define DESERIALIZE // default is serialize 3 | 4 | using System; 5 | using System.Diagnostics; 6 | using System.Net.Http; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using Newtonsoft.Json; 11 | 12 | namespace Benchmarks.Serializers 13 | { 14 | public class RequestPerSecondClient 15 | { 16 | private const string HttpsLocalhost = "https://localhost:5001/"; 17 | 18 | public async Task Run(bool serialize, bool isUtf8Json) 19 | { 20 | await Task.Delay(TimeSpan.FromSeconds(5)); 21 | 22 | var client = new HttpClient(); 23 | var json = JsonConvert.SerializeObject(new Models.ThousandSmallClassList()); 24 | 25 | // Warmup, just in case 26 | for (int i = 0; i < 100; i++) 27 | { 28 | await DoRequest(json, client, serialize); 29 | } 30 | 31 | int count = 0; 32 | 33 | Stopwatch sw = new Stopwatch(); 34 | sw.Start(); 35 | 36 | while (sw.Elapsed < TimeSpan.FromSeconds(1)) 37 | { 38 | Interlocked.Increment(ref count); 39 | await DoRequest(json, client, serialize); 40 | } 41 | 42 | Console.Beep(); 43 | Console.WriteLine("Requests in one second: " + count); 44 | Console.ReadLine(); 45 | } 46 | 47 | 48 | private async Task DoRequest(string json, HttpClient client, bool serialize) 49 | { 50 | if (serialize) 51 | await DoSerializeRequest(client); 52 | else 53 | await DoDeserializeRequest(json, client); 54 | } 55 | private async Task DoDeserializeRequest(string json, HttpClient client) 56 | { 57 | var uri = new Uri(HttpsLocalhost + "mvc/DeserializeThousandSmallClassList"); 58 | var content = new StringContent(json, Encoding.UTF8, "application/json"); 59 | var result = await client.PostAsync(uri, content); 60 | result.Dispose(); 61 | } 62 | 63 | private async Task DoSerializeRequest(HttpClient client) 64 | { 65 | var uri = HttpsLocalhost + "mvc/SerializeThousandSmallClassList"; 66 | var result = await client.GetAsync(uri); 67 | result.Dispose(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Benchmarks/Serializers/SerializeSmallClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.Serialization; 4 | using System.Runtime.Serialization.Json; 5 | using System.Text.Json.Serialization; 6 | using BenchmarkDotNet.Attributes; 7 | using Jil; 8 | using Newtonsoft.Json; 9 | using JsonSerializer = System.Text.Json.JsonSerializer; 10 | using SST = ServiceStack.Text; 11 | 12 | namespace Benchmarks.Serializers 13 | { 14 | //public class SerializeCustomer 15 | //{ 16 | // [DataContract] 17 | // class BigClass 18 | // { 19 | // [DataMember] 20 | // public DateTime DateOfBirth { get; set; } 21 | // [DataMember] 22 | // public string FirstName { get; set; } 23 | // [DataMember] 24 | // public string LastName { get; set; } 25 | // [DataMember] 26 | // public int NumPurchases { get; set; } 27 | // } 28 | 29 | // private BigClass _customer; 30 | 31 | // [GlobalSetup] 32 | // public void Setup() 33 | // { 34 | // _customer = new BigClass() 35 | // { 36 | // DateOfBirth = new DateTime(1955, 10, 28), 37 | // FirstName = "Bill", 38 | // LastName = "Gates", 39 | // NumPurchases = 1521 40 | // }; 41 | // } 42 | 43 | // [Benchmark] 44 | // public string RunSystemTextJson() 45 | // { 46 | // return JsonSerializer.Serialize(_customer); 47 | // } 48 | 49 | // [Benchmark] 50 | // public string Newtonsoft() 51 | // { 52 | // return JsonConvert.SerializeObject(_customer); 53 | // } 54 | 55 | // [Benchmark] 56 | // public string DataContractJsonSerializer() 57 | // { 58 | // using (MemoryStream stream1 = new MemoryStream()) 59 | // { 60 | // DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(BigClass)); 61 | // //TODO: Possibly change MemoryStream to StringWriter for performance 62 | // ser.WriteObject(stream1, _customer); 63 | // stream1.Position = 0; 64 | 65 | // // deserialize: 66 | // //var p2 = (BigClass)ser.ReadObject(stream1); 67 | 68 | // using var sr = new StreamReader(stream1); 69 | // return sr.ReadToEnd(); 70 | // } 71 | // } 72 | 73 | // [Benchmark] 74 | // public string Jil() 75 | // { 76 | // using var output = new StringWriter(); 77 | // JSON.Serialize( 78 | // _customer, 79 | // output 80 | // ); 81 | // return output.ToString(); 82 | // } 83 | 84 | // [Benchmark] 85 | // public string Utf8Json() 86 | // { 87 | // return JsonSerializer.Serialize(_customer); //.ToJsonString(_customer); 88 | // } 89 | 90 | // [Benchmark] 91 | // public string ServiceStack() 92 | // { 93 | // return SST.JsonSerializer.SerializeToString(_customer); 94 | // } 95 | 96 | 97 | //} 98 | } 99 | -------------------------------------------------------------------------------- /Benchmarks/Serializers/SerializeToStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.Serialization; 4 | using System.Runtime.Serialization.Json; 5 | using System.Text; 6 | using System.Text.Json; 7 | using System.Text.Json.Serialization; 8 | using BenchmarkDotNet.Attributes; 9 | using Jil; 10 | using Newtonsoft.Json; 11 | using JsonSerializer = System.Text.Json.JsonSerializer; 12 | using SST = ServiceStack.Text; 13 | 14 | namespace Benchmarks.Serializers 15 | { 16 | public class SerializeToStream where T : new() 17 | { 18 | private Newtonsoft.Json.JsonSerializer _newtonSoftSerializer; 19 | 20 | private T _instance; 21 | private DataContractJsonSerializer _dataContractJsonSerializer; 22 | private MemoryStream _memoryStream; 23 | private StreamWriter _streamWriter; 24 | private Utf8JsonWriter _utf8JsonWriter; 25 | 26 | [GlobalSetup] 27 | public void Setup() 28 | { 29 | _instance = new T(); 30 | _newtonSoftSerializer = new Newtonsoft.Json.JsonSerializer(); 31 | _dataContractJsonSerializer = new DataContractJsonSerializer(typeof(T)); 32 | _memoryStream = new MemoryStream(capacity: short.MaxValue); 33 | _streamWriter = new StreamWriter(_memoryStream, Encoding.UTF8); 34 | _utf8JsonWriter = new Utf8JsonWriter(_memoryStream); 35 | 36 | } 37 | 38 | public MemoryStream GetMemoryStream() 39 | { 40 | return _memoryStream; 41 | } 42 | 43 | public StreamWriter GetStreamWriter() 44 | { 45 | return _streamWriter; 46 | } 47 | 48 | [Benchmark] 49 | public void RunSystemTextJson() 50 | { 51 | _memoryStream.Position = 0; 52 | _utf8JsonWriter.Reset(); 53 | JsonSerializer.Serialize(_utf8JsonWriter, _instance); 54 | } 55 | 56 | [Benchmark] 57 | public void RunNewtonsoft() 58 | { 59 | _memoryStream.Position = 0; 60 | _newtonSoftSerializer.Serialize(_streamWriter, _instance); 61 | } 62 | 63 | [Benchmark] 64 | public void RunDataContractJsonSerializer() 65 | { 66 | _memoryStream.Position = 0; 67 | _dataContractJsonSerializer.WriteObject(_memoryStream, _instance); 68 | } 69 | 70 | [GlobalSetup(Target = nameof(RunJil))] 71 | public void JilSetup() 72 | { 73 | Setup(); 74 | RunJil(); 75 | } 76 | [Benchmark] 77 | public void RunJil() 78 | { 79 | _memoryStream.Position = 0; 80 | 81 | JSON.Serialize( 82 | _instance, 83 | _streamWriter 84 | ); 85 | } 86 | 87 | [Benchmark] 88 | public void RunUtf8Json() 89 | { 90 | _memoryStream.Position = 0; 91 | Utf8Json.JsonSerializer.Serialize(_memoryStream, _instance); 92 | } 93 | 94 | [Benchmark] 95 | public void RunServiceStack() 96 | { 97 | _memoryStream.Position = 0; 98 | SST.JsonSerializer.SerializeToStream(_instance, _memoryStream); 99 | } 100 | 101 | 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Benchmarks/Serializers/SerializeToString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.Serialization; 4 | using System.Runtime.Serialization.Json; 5 | using System.Text.Json.Serialization; 6 | using BenchmarkDotNet.Attributes; 7 | using Newtonsoft.Json; 8 | using JsonSerializer = System.Text.Json.JsonSerializer; 9 | using SST = ServiceStack.Text; 10 | 11 | namespace Benchmarks.Serializers 12 | { 13 | public class SerializeToString where T : class, new() 14 | { 15 | 16 | private T _instance; 17 | private DataContractJsonSerializer _dataContractJsonSerializer; 18 | 19 | [GlobalSetup] 20 | public void Setup() 21 | { 22 | _instance = _instance ?? new T(); 23 | _dataContractJsonSerializer = _dataContractJsonSerializer ?? new DataContractJsonSerializer(typeof(T)); 24 | } 25 | 26 | [Benchmark] 27 | public string RunSystemTextJson() 28 | { 29 | return JsonSerializer.Serialize(_instance); 30 | } 31 | 32 | [Benchmark] 33 | public string RunNewtonsoft() 34 | { 35 | return JsonConvert.SerializeObject(_instance); 36 | } 37 | 38 | [Benchmark] 39 | public string RunDataContractJsonSerializer() 40 | { 41 | using (MemoryStream stream1 = new MemoryStream()) 42 | { 43 | _dataContractJsonSerializer.WriteObject(stream1, _instance); 44 | stream1.Position = 0; 45 | using var sr = new StreamReader(stream1); 46 | return sr.ReadToEnd(); 47 | } 48 | } 49 | 50 | [GlobalSetup(Target = nameof(RunJil))] 51 | public void JilSetup() 52 | { 53 | Setup(); 54 | RunJil(); 55 | } 56 | [Benchmark] 57 | public string RunJil() 58 | { 59 | return Jil.JSON.Serialize(_instance); 60 | } 61 | 62 | [Benchmark] 63 | public string RunUtf8Json() 64 | { 65 | return Utf8Json.JsonSerializer.ToJsonString(_instance); 66 | } 67 | 68 | [Benchmark] 69 | public string RunServiceStack() 70 | { 71 | return SST.JsonSerializer.SerializeToString(_instance); 72 | } 73 | 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/BenchmarksServerDotNetCore3.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnet.webapi.client\5.2.6\lib\netstandard2.0\System.Net.Http.Formatting.dll 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | using BenchmarksServerDotNetCore3.Models; 9 | 10 | namespace BenchmarksServerDotNetCore3.Controllers 11 | { 12 | public class HomeController : Controller 13 | { 14 | private readonly ILogger _logger; 15 | 16 | public HomeController(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | public IActionResult Index() 22 | { 23 | return View(); 24 | } 25 | 26 | public IActionResult Privacy() 27 | { 28 | return View(); 29 | } 30 | 31 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 32 | public IActionResult Error() 33 | { 34 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Controllers/JsonSerializeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace BenchmarksServerDotNetCore3.Controllers 4 | { 5 | [Route("mvc")] 6 | public class JsonSerializeController : Controller 7 | { 8 | 9 | private static Benchmarks.Serializers.Models.ThousandSmallClassList _thousandSmallClassList 10 | = new Benchmarks.Serializers.Models.ThousandSmallClassList(); 11 | 12 | [HttpPost("DeserializeThousandSmallClassList")] 13 | [Consumes("application/json")] 14 | public ActionResult DeserializeThousandSmallClassList([FromBody]Benchmarks.Serializers.Models.ThousandSmallClassList obj) => Ok(); 15 | 16 | [HttpGet("SerializeThousandSmallClassList")] 17 | [Produces("application/json")] 18 | public object SerializeThousandSmallClassList() => _thousandSmallClassList; 19 | } 20 | } -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Formatters/JilFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Net.Http.Formatting; 7 | using System.Net.Http.Headers; 8 | using System.Reflection; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using Jil; 12 | using Microsoft.AspNetCore.Mvc.Formatters; 13 | 14 | namespace BenchmarksServerDotNetCore3.Formatters 15 | { 16 | //public class JilFormatter2 : IInputFormatter 17 | //{ 18 | // private readonly Options _jilOptions; 19 | 20 | // public bool CanRead(InputFormatterContext context) 21 | // { 22 | // if (context.ModelType == null) 23 | // { 24 | // throw new ArgumentNullException("type"); 25 | // } 26 | // return true; 27 | // } 28 | 29 | // public Task ReadAsync(InputFormatterContext context) 30 | // { 31 | // var httpContextRequest = context.HttpContext.Request; 32 | 33 | // //if (!httpContextRequest.ContentLength.HasValue || httpContextRequest.ContentLength == 0) 34 | // //{ 35 | // // return await InputFormatterResult.FailureAsync(); 36 | // //} 37 | 38 | // using (var reader = context.ReaderFactory(httpContextRequest.Body, Encoding.UTF8)) 39 | // { 40 | // //string readToEndAsync = await reader.ReadToEndAsync(); 41 | // //blogPost.Content = readToEndAsync; 42 | // //return await InputFormatterResult.SuccessAsync(blogPost); 43 | // return Task.FromResult(this.DeserializeFromStream(context.ModelType, reader.)); 44 | // } 45 | 46 | // return Task.FromResult(this.DeserializeFromStream(context.ModelType, context.)); 47 | // } 48 | 49 | // private object DeserializeFromStream(Type type,Stream readStream) 50 | // { 51 | // try 52 | // { 53 | // using (var reader = new StreamReader(readStream)) 54 | // { 55 | // MethodInfo method = typeof(JSON).GetMethod("Deserialize", new Type[] { typeof(TextReader),typeof(Options) }); 56 | // MethodInfo generic = method.MakeGenericMethod(type); 57 | // return generic.Invoke(this, new object[]{reader, _jilOptions}); 58 | // } 59 | // } 60 | // catch 61 | // { 62 | // return null; 63 | // } 64 | 65 | // } 66 | //} 67 | public class JilFormatter : MediaTypeFormatter 68 | { 69 | private readonly Options _jilOptions; 70 | public JilFormatter() 71 | { 72 | _jilOptions=new Options(dateFormat:DateTimeFormat.ISO8601); 73 | SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); 74 | 75 | SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true)); 76 | SupportedEncodings.Add(new UnicodeEncoding(bigEndian: false, byteOrderMark: true, throwOnInvalidBytes: true)); 77 | } 78 | public override bool CanReadType(Type type) 79 | { 80 | if (type == null) 81 | { 82 | throw new ArgumentNullException("type"); 83 | } 84 | return true; 85 | } 86 | 87 | public override bool CanWriteType(Type type) 88 | { 89 | if (type == null) 90 | { 91 | throw new ArgumentNullException("type"); 92 | } 93 | return true; 94 | } 95 | 96 | public override Task ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger) 97 | { 98 | return Task.FromResult(this.DeserializeFromStream(type, readStream)); 99 | } 100 | 101 | 102 | private object DeserializeFromStream(Type type,Stream readStream) 103 | { 104 | try 105 | { 106 | using (var reader = new StreamReader(readStream)) 107 | { 108 | MethodInfo method = typeof(JSON).GetMethod("Deserialize", new Type[] { typeof(TextReader),typeof(Options) }); 109 | MethodInfo generic = method.MakeGenericMethod(type); 110 | return generic.Invoke(this, new object[]{reader, _jilOptions}); 111 | } 112 | } 113 | catch 114 | { 115 | return null; 116 | } 117 | 118 | } 119 | 120 | 121 | public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, TransportContext transportContext) 122 | { 123 | var streamWriter = new StreamWriter(writeStream); 124 | JSON.Serialize(value, streamWriter, _jilOptions); 125 | streamWriter.Flush(); 126 | return Task.FromResult(writeStream); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Formatters/Utf8JsonFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc.Formatters; 7 | using Utf8Json; 8 | 9 | namespace BenchmarksServerDotNetCore3.Formatters 10 | { 11 | internal sealed class Utf8JsonInputFormatter1 : IInputFormatter 12 | { 13 | private readonly IJsonFormatterResolver _resolver; 14 | 15 | public Utf8JsonInputFormatter1() : this(null) { } 16 | public Utf8JsonInputFormatter1(IJsonFormatterResolver resolver) 17 | { 18 | _resolver = resolver ?? JsonSerializer.DefaultResolver; 19 | } 20 | 21 | public bool CanRead(InputFormatterContext context) => context.HttpContext.Request.ContentType.StartsWith("application/json"); 22 | 23 | public async Task ReadAsync(InputFormatterContext context) 24 | { 25 | var request = context.HttpContext.Request; 26 | 27 | if (request.Body.CanSeek && request.Body.Length == 0) 28 | return await InputFormatterResult.NoValueAsync(); 29 | 30 | var result = await JsonSerializer.NonGeneric.DeserializeAsync(context.ModelType, request.Body, _resolver); 31 | return await InputFormatterResult.SuccessAsync(result); 32 | } 33 | } 34 | 35 | 36 | internal sealed class Utf8JsonOutputFormatter1 : IOutputFormatter 37 | { 38 | private readonly IJsonFormatterResolver _resolver; 39 | 40 | public Utf8JsonOutputFormatter1() : this(null) { } 41 | public Utf8JsonOutputFormatter1(IJsonFormatterResolver resolver) 42 | { 43 | _resolver = resolver ?? JsonSerializer.DefaultResolver; 44 | } 45 | 46 | public bool CanWriteResult(OutputFormatterCanWriteContext context) => true; 47 | 48 | 49 | public async Task WriteAsync(OutputFormatterWriteContext context) 50 | { 51 | if (!context.ContentTypeIsServerDefined) 52 | context.HttpContext.Response.ContentType = "application/json"; 53 | 54 | if (context.ObjectType == typeof(object)) 55 | { 56 | await JsonSerializer.NonGeneric.SerializeAsync(context.HttpContext.Response.Body, context.Object, _resolver); 57 | } 58 | else 59 | { 60 | await JsonSerializer.NonGeneric.SerializeAsync(context.ObjectType, context.HttpContext.Response.Body, context.Object, _resolver); 61 | } 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BenchmarksServerDotNetCore3.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace BenchmarksServerDotNetCore3 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureLogging(logging => 22 | { 23 | logging.ClearProviders(); 24 | //logging.AddConsole(); 25 | }) 26 | .ConfigureWebHostDefaults(webBuilder => 27 | { 28 | webBuilder.UseStartup(); 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using BenchmarksServerDotNetCore3.Formatters; 6 | using Microsoft.AspNetCore.Builder; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.AspNetCore.HttpsPolicy; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Microsoft.AspNetCore.Mvc.Formatters; 11 | using Microsoft.Extensions.Configuration; 12 | using Microsoft.Extensions.DependencyInjection; 13 | using Microsoft.Extensions.Hosting; 14 | using Utf8Json.AspNetCoreMvcFormatter; 15 | using Utf8Json.Resolvers; 16 | 17 | namespace BenchmarksServerDotNetCore3 18 | { 19 | public class Startup 20 | { 21 | public Startup(IConfiguration configuration) 22 | { 23 | Configuration = configuration; 24 | } 25 | 26 | public IConfiguration Configuration { get; } 27 | 28 | // This method gets called by the runtime. Use this method to add services to the container. 29 | public void ConfigureServices(IServiceCollection services) 30 | { 31 | services.AddControllersWithViews() 32 | 33 | //Uncomment for Newtonsoft 34 | //.AddNewtonsoftJson() 35 | 36 | //Uncomment for Utf8Json 37 | .AddMvcOptions(option => 38 | { 39 | 40 | option.OutputFormatters.Clear(); 41 | // can pass IJsonFormatterResolver for customize. 42 | option.OutputFormatters.Add(new Utf8JsonOutputFormatter1(StandardResolver.Default)); 43 | option.InputFormatters.Clear(); 44 | // if does not pass, library should use JsonSerializer.DefaultResolver. 45 | option.InputFormatters.Add(new Utf8JsonInputFormatter1()); 46 | }); 47 | ; 48 | 49 | //services.AddMvc(); 50 | 51 | } 52 | 53 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 54 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 55 | { 56 | if (env.IsDevelopment()) 57 | { 58 | app.UseDeveloperExceptionPage(); 59 | } 60 | else 61 | { 62 | app.UseExceptionHandler("/Home/Error"); 63 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 64 | app.UseHsts(); 65 | } 66 | app.UseHttpsRedirection(); 67 | app.UseStaticFiles(); 68 | 69 | 70 | app.UseRouting(); 71 | 72 | app.UseAuthorization(); 73 | 74 | app.UseEndpoints(endpoints => 75 | { 76 | endpoints.MapControllerRoute( 77 | name: "default", 78 | pattern: "{controller=Home}/{action=Index}/{id?}"); 79 | }); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 |
6 |

Welcome

7 |

Learn about building Web apps with ASP.NET Core.

8 |
9 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

@ViewData["Title"]

5 | 6 |

Use this page to detail your site's privacy policy.

7 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

12 | Request ID: @Model.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - BenchmarksServerDotNetCore3 7 | 8 | 9 | 10 | 11 |
12 | 31 |
32 |
33 |
34 | @RenderBody() 35 |
36 |
37 | 38 |
39 |
40 | © 2019 - BenchmarksServerDotNetCore3 - Privacy 41 |
42 |
43 | 44 | 45 | 46 | @RenderSection("Scripts", required: false) 47 | 48 | 49 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using BenchmarksServerDotNetCore3 2 | @using BenchmarksServerDotNetCore3.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | /* Provide sufficient contrast against white background */ 11 | a { 12 | color: #0366d6; 13 | } 14 | 15 | .btn-primary { 16 | color: #fff; 17 | background-color: #1b6ec2; 18 | border-color: #1861ac; 19 | } 20 | 21 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 22 | color: #fff; 23 | background-color: #1b6ec2; 24 | border-color: #1861ac; 25 | } 26 | 27 | /* Sticky footer styles 28 | -------------------------------------------------- */ 29 | html { 30 | font-size: 14px; 31 | } 32 | @media (min-width: 768px) { 33 | html { 34 | font-size: 16px; 35 | } 36 | } 37 | 38 | .border-top { 39 | border-top: 1px solid #e5e5e5; 40 | } 41 | .border-bottom { 42 | border-bottom: 1px solid #e5e5e5; 43 | } 44 | 45 | .box-shadow { 46 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 47 | } 48 | 49 | button.accept-policy { 50 | font-size: 1rem; 51 | line-height: inherit; 52 | } 53 | 54 | /* Sticky footer styles 55 | -------------------------------------------------- */ 56 | html { 57 | position: relative; 58 | min-height: 100%; 59 | } 60 | 61 | body { 62 | /* Margin bottom by footer height */ 63 | margin-bottom: 60px; 64 | } 65 | .footer { 66 | position: absolute; 67 | bottom: 0; 68 | width: 100%; 69 | white-space: nowrap; 70 | line-height: 60px; /* Vertically center the text there */ 71 | } 72 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelscodingspot/PracticalDebugging/1d4b155274460f4bacc39dfb18dc699919f0c224/BenchmarksServerDotNetCore3/wwwroot/favicon.ico -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2018 Twitter, Inc. 4 | Copyright (c) 2011-2018 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors 4 | * Copyright 2011-2019 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (c) .NET Foundation. All rights reserved. 3 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 4 | // @version v3.2.11 5 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /BenchmarksServerDotNetCore3/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /Calculator/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Calculator/Calculator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4BBEF579-7C0B-4F02-A63C-2AB6C143593F} 8 | Exe 9 | Calculator 10 | Calculator 11 | v4.7.1 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Calculator/CalculatorEngine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Calculator 4 | { 5 | internal class CalculatorEngine 6 | { 7 | public CalculatorEngine() 8 | { 9 | } 10 | 11 | internal int DoOperation(int operationId, int firstNumber, int secondNumber) 12 | { 13 | switch (operationId) 14 | { 15 | case 1: 16 | return Add(firstNumber, secondNumber); 17 | case 2: 18 | return Substract(firstNumber, secondNumber); 19 | case 3: 20 | return Multiply(firstNumber, secondNumber); 21 | case 4: 22 | return Divide(firstNumber, secondNumber); 23 | default: 24 | throw new InvalidOperationException($"The operation Id {operationId} is invalid."); 25 | 26 | } 27 | } 28 | 29 | private int Add(int firstNumber, int secondNumber) 30 | { 31 | var result = firstNumber + secondNumber; 32 | return result; 33 | } 34 | 35 | private int Substract(int firstNumber, int secondNumber) 36 | { 37 | var result = firstNumber - secondNumber; 38 | return result; 39 | } 40 | 41 | private int Multiply(int firstNumber, int secondNumber) 42 | { 43 | var result = firstNumber * secondNumber; 44 | return result; 45 | } 46 | 47 | private int Divide(int firstNumber, int secondNumber) 48 | { 49 | var result = firstNumber / secondNumber; 50 | return result; 51 | } 52 | 53 | } 54 | } -------------------------------------------------------------------------------- /Calculator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Calculator 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | GetOperationItems(out int operationId, out int firstNumber, out int secondNumber); 14 | var calc = new CalculatorEngine(); 15 | double result = calc.DoOperation(operationId, firstNumber, secondNumber); 16 | Console.WriteLine("The result is: " + result); 17 | Console.WriteLine("Press any key to continue"); 18 | Console.ReadKey(); 19 | } 20 | 21 | private static void GetOperationItems(out int operationId, out int firstNumber, out int secondNumber) 22 | { 23 | Console.WriteLine("Enter operation:"); 24 | Console.WriteLine("1. Add"); 25 | Console.WriteLine("2. Substract"); 26 | Console.WriteLine("3. Multiply"); 27 | Console.WriteLine("4. Divide"); 28 | operationId = int.Parse(Console.ReadLine()); 29 | Console.WriteLine("Enter first number"); 30 | firstNumber = int.Parse(Console.ReadLine()); 31 | Console.WriteLine("Enter second number"); 32 | secondNumber = int.Parse(Console.ReadLine()); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Calculator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Calculator")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Calculator")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4bbef579-7c0b-4f02-a63c-2ab6c143593f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "3.1.8", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Microsoft.AspNetCore.Mvc; 8 | using PracticalDebuggingWeb.Models; 9 | using Serilog; 10 | 11 | namespace PracticalDebuggingWeb.Controllers 12 | { 13 | public class HomeController : Controller 14 | { 15 | public IActionResult Index() 16 | { 17 | Log.Information("Home/Index"); 18 | return View(); 19 | } 20 | 21 | public async Task LongRunning() 22 | { 23 | await Task.Delay(45000); 24 | return Ok(); 25 | } 26 | 27 | public IActionResult Privacy() 28 | { 29 | return View(); 30 | } 31 | 32 | public IActionResult SignIn() 33 | { 34 | return View(); 35 | } 36 | 37 | public IActionResult Crash() 38 | { 39 | ThreadPool.QueueUserWorkItem((s) => 40 | { 41 | Thread.Sleep(1500); 42 | throw new Exception("Let's crash this party"); 43 | }); 44 | return View(); 45 | } 46 | 47 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 48 | public IActionResult Error() 49 | { 50 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Controllers/PriceCalculatorController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Microsoft.AspNetCore.Mvc; 8 | using PracticalDebuggingWeb.Controllers.Services; 9 | using PracticalDebuggingWeb.Models; 10 | using Serilog; 11 | 12 | namespace PracticalDebuggingWeb.Controllers 13 | { 14 | public class PriceCalculatorController : Controller 15 | { 16 | public async Task Calculate(string price, string convertCurrency, string couponCode, string discount) 17 | { 18 | var result = await new PriceCalculator().Calculate(price, convertCurrency, couponCode, discount); 19 | return View("Result", result); 20 | } 21 | 22 | 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Controllers/Services/CouponService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Http; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace PracticalDebuggingWeb.Controllers.Services 7 | { 8 | internal class CouponService 9 | { 10 | internal static double GetCouponDiscount(string couponCode) 11 | { 12 | if (couponCode == "Employee2423432") 13 | { 14 | return 25; 15 | } 16 | else if (couponCode == "VIP_2020_rmg") 17 | { 18 | return 15; 19 | } 20 | else 21 | { 22 | AutoResetEvent are = new AutoResetEvent(false); 23 | double result = 0; 24 | ThreadPool.QueueUserWorkItem((_) => 25 | { 26 | var httpClient = HttpClientFactory.Create(); 27 | var res = httpClient.GetAsync("https://couponservice.com/api/Discount?couponCode=" + couponCode) 28 | .GetAwaiter().GetResult(); 29 | var content = res.Content.ReadAsStringAsync().GetAwaiter().GetResult(); 30 | result = double.Parse(content); 31 | are.Set(); 32 | }); 33 | are.WaitOne(); 34 | return result; 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Controllers/Services/Currency.cs: -------------------------------------------------------------------------------- 1 | namespace PracticalDebuggingWeb.Controllers.Services 2 | { 3 | public enum Currency { USD, EURO, GBP}; 4 | } 5 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Controllers/Services/CurrencyConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Http; 3 | 4 | namespace PracticalDebuggingWeb.Controllers.Services 5 | { 6 | internal class CurrencyConverter 7 | { 8 | internal static double ConvertToUsd(string price, Currency currency) 9 | { 10 | var exchangeRate = GetExchangeRate(currency, Currency.USD); 11 | var pricenum = double.Parse(price); 12 | return pricenum * exchangeRate; 13 | } 14 | 15 | private static double GetExchangeRate(Currency from, Currency to) 16 | { 17 | var httpClient = new HttpClient(); 18 | //TODO: Go to https://exchangeratesapi.io/ 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Controllers/Services/CurrencyService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PracticalDebuggingWeb.Controllers.Services 4 | { 5 | internal class CurrencyService 6 | { 7 | internal static Currency GetCurrencyFromString(string convertCurrency) 8 | { 9 | var cur = Enum.Parse(convertCurrency, true); 10 | return cur; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Controllers/Services/PriceCalculator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingWeb.Controllers.Services 8 | { 9 | 10 | 11 | public class PriceCalculator 12 | { 13 | 14 | public async Task Calculate(string price, string convertCurrency, string couponCode, string discount) 15 | { 16 | var currency = CurrencyService.GetCurrencyFromString(convertCurrency); 17 | double priceUsd; 18 | if (currency == Currency.USD) 19 | { 20 | priceUsd = double.Parse(price); 21 | } 22 | else 23 | { 24 | priceUsd = CurrencyConverter.ConvertToUsd(price, currency); 25 | } 26 | 27 | if (!string.IsNullOrEmpty(couponCode)) 28 | { 29 | double couponDiscountPercent = CouponService.GetCouponDiscount(couponCode); 30 | var couponDiscount = GetDiscount(couponDiscountPercent, priceUsd); 31 | priceUsd -= couponDiscount; 32 | } 33 | 34 | var discountNum = GetDiscount(double.Parse(discount), priceUsd); 35 | return priceUsd - discountNum; 36 | } 37 | 38 | private double GetDiscount(double discount, double price) 39 | { 40 | return discount / 100.0 * price; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PracticalDebuggingWeb.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } -------------------------------------------------------------------------------- /PracticalDebuggingWeb/PracticalDebuggingWeb.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | using Serilog; 11 | 12 | namespace PracticalDebuggingWeb 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | Log.Logger = new LoggerConfiguration() 19 | .MinimumLevel.Debug() 20 | .WriteTo.File("Logs\\weblog.txt", rollingInterval: RollingInterval.Day) 21 | .CreateLogger(); 22 | AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( 23 | (s, e) => 24 | { 25 | Log.Fatal(e.ExceptionObject as Exception, $"Unhandled exception. IsTerminating: {e.IsTerminating}"); 26 | }); 27 | CreateWebHostBuilder(args).Build().Run(); 28 | } 29 | 30 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 31 | WebHost.CreateDefaultBuilder(args) 32 | .UseSerilog() 33 | .UseStartup(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.AspNetCore.HttpsPolicy; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Microsoft.Extensions.Configuration; 11 | using Microsoft.Extensions.DependencyInjection; 12 | 13 | namespace PracticalDebuggingWeb 14 | { 15 | public class Startup 16 | { 17 | public Startup(IConfiguration configuration) 18 | { 19 | Configuration = configuration; 20 | } 21 | 22 | public IConfiguration Configuration { get; } 23 | 24 | // This method gets called by the runtime. Use this method to add services to the container. 25 | public void ConfigureServices(IServiceCollection services) 26 | { 27 | services.Configure(options => 28 | { 29 | // This lambda determines whether user consent for non-essential cookies is needed for a given request. 30 | options.CheckConsentNeeded = context => true; 31 | options.MinimumSameSitePolicy = SameSiteMode.None; 32 | }); 33 | 34 | 35 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 36 | } 37 | 38 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 39 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 40 | { 41 | //if (env.IsDevelopment()) 42 | //{ 43 | // //app.UseDeveloperExceptionPage(); 44 | //} 45 | //else 46 | { 47 | app.UseExceptionHandler("/Home/Error"); 48 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 49 | app.UseHsts(); 50 | } 51 | 52 | app.UseHttpsRedirection(); 53 | app.UseStaticFiles(); 54 | app.UseCookiePolicy(); 55 | 56 | app.UseMvc(routes => 57 | { 58 | routes.MapRoute( 59 | name: "default", 60 | template: "{controller=Home}/{action=Index}/{id?}"); 61 | }); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Home/Crash.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Crashing"; 3 | } 4 |

    @ViewData["Title"]

    5 | 6 |

    Crashing...

    7 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 |
    6 |

    Price Calculator

    7 |
    8 |
    9 |
    10 |
    11 |

    Price (USD)

    12 | 13 |
    14 | Convert currency 15 | 16 | 21 |
    22 | 23 |

    Coupon code

    24 | 25 |

    Additional Discount

    26 | 27 | 28 | 29 | 30 | 31 |
    32 | 33 | 34 |
    35 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

    @ViewData["Title"]

    5 | 6 |

    Use this page to detail your site's privacy policy.

    7 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Home/SignIn.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Sign in"; 3 | } 4 |

    @ViewData["Title"]

    5 | 6 | 15 | 16 |
    17 | Avatar 18 |
    19 | 20 |
    21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 31 |
    32 | 33 |
    34 | 35 | Forgot password? 36 |
    37 | 38 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/PriceCalculator/Result.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Result Page"; 3 | } 4 | 5 |

    Result price: @Model

    6 |

    Currency: USD

    7 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

    Error.

    7 |

    An error occurred while processing your request.

    8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

    12 | Request ID: @Model.RequestId 13 |

    14 | } 15 | 16 |

    Development Mode

    17 |

    18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

    20 |

    21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

    26 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Shared/_CookieConsentPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Http.Features 2 | 3 | @{ 4 | var consentFeature = Context.Features.Get(); 5 | var showBanner = !consentFeature?.CanTrack ?? false; 6 | var cookieString = consentFeature?.CreateConsentCookie(); 7 | } 8 | 9 | @if (showBanner) 10 | { 11 | 17 | 25 | } 26 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Advanced Production Debugging Techniques 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 21 |
    22 | 47 |
    48 |
    49 | 50 |
    51 | @RenderBody() 52 |
    53 |
    54 | 55 |
    56 |
    57 | © 2019 - PracticalDebuggingWeb - Privacy 58 |
    59 |
    60 | 61 | 62 | 63 | 64 | 65 | 66 | 72 | 78 | 79 | 80 | 81 | @RenderSection("Scripts", required: false) 82 | 83 | 84 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using PracticalDebuggingWeb 2 | @using PracticalDebuggingWeb.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | /* Sticky footer styles 11 | -------------------------------------------------- */ 12 | html { 13 | font-size: 14px; 14 | } 15 | @media (min-width: 768px) { 16 | html { 17 | font-size: 16px; 18 | } 19 | } 20 | 21 | .border-top { 22 | border-top: 1px solid #e5e5e5; 23 | } 24 | .border-bottom { 25 | border-bottom: 1px solid #e5e5e5; 26 | } 27 | 28 | .box-shadow { 29 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 30 | } 31 | 32 | button.accept-policy { 33 | font-size: 1rem; 34 | line-height: inherit; 35 | } 36 | 37 | /* Sticky footer styles 38 | -------------------------------------------------- */ 39 | html { 40 | position: relative; 41 | min-height: 100%; 42 | } 43 | 44 | body { 45 | /* Margin bottom by footer height */ 46 | margin-bottom: 60px; 47 | } 48 | .footer { 49 | position: absolute; 50 | bottom: 0; 51 | width: 100%; 52 | white-space: nowrap; 53 | /* Set the fixed height of the footer here */ 54 | height: 60px; 55 | line-height: 60px; /* Vertically center the text there */ 56 | } 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | /* Bordered form */ 66 | form { 67 | border: 3px solid #f1f1f1; 68 | } 69 | 70 | /* Full-width inputs */ 71 | input[type=text], input[type=password] { 72 | width: 100%; 73 | padding: 12px 20px; 74 | margin: 8px 0; 75 | display: inline-block; 76 | border: 1px solid #ccc; 77 | box-sizing: border-box; 78 | } 79 | 80 | /* Set a style for all buttons */ 81 | button { 82 | background-color: #4CAF50; 83 | color: white; 84 | padding: 14px 20px; 85 | margin: 8px 0; 86 | border: none; 87 | cursor: pointer; 88 | width: 100%; 89 | } 90 | 91 | /* Add a hover effect for buttons */ 92 | button:hover { 93 | opacity: 0.8; 94 | } 95 | 96 | /* Extra style for the cancel button (red) */ 97 | .cancelbtn { 98 | width: auto; 99 | padding: 10px 18px; 100 | background-color: #f44336; 101 | } 102 | 103 | /* Center the avatar image inside this container */ 104 | .imgcontainer { 105 | text-align: center; 106 | margin: 24px 0 12px 0; 107 | } 108 | 109 | /* Avatar image */ 110 | img.avatar { 111 | width: 40%; 112 | border-radius: 50%; 113 | } 114 | 115 | /* Add padding to containers */ 116 | .container { 117 | padding: 16px; 118 | } 119 | 120 | /* The "Forgot password" text */ 121 | span.psw { 122 | float: right; 123 | padding-top: 16px; 124 | } 125 | 126 | /* Change styles for span and cancel button on extra small screens */ 127 | @media screen and (max-width: 300px) { 128 | span.psw { 129 | display: block; 130 | float: none; 131 | } 132 | .cancelbtn { 133 | width: 100%; 134 | } 135 | } 136 | 137 | .outerForm { 138 | border: none; 139 | } 140 | 141 | form { 142 | margin-left: 260px; 143 | max-width: 600px; 144 | } 145 | 146 | form p { 147 | text-align: left; 148 | margin-bottom: 3px; 149 | margin-top: 10px; 150 | } 151 | 152 | form span { 153 | text-align: left !important; 154 | } 155 | 156 | .convertContainer { 157 | display:block; 158 | text-align: left; 159 | } 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelscodingspot/PracticalDebugging/1d4b155274460f4bacc39dfb18dc699919f0c224/PracticalDebuggingWeb/wwwroot/favicon.ico -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2018 Twitter, Inc. 4 | Copyright (c) 2011-2018 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors 4 | * Copyright 2011-2019 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (c) .NET Foundation. All rights reserved. 3 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 4 | // @version v3.2.11 5 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /PracticalDebuggingWeb/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /PracticalDebugingDemos.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.902 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PracticalDebuggingDemos", "PracticalDebugingDemos\PracticalDebuggingDemos.csproj", "{3A0132C6-FB69-4403-BCE9-C592371DEA7C}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PracticalDebuggingWeb", "PracticalDebuggingWeb\PracticalDebuggingWeb.csproj", "{548832B4-08D3-4D7A-806A-FA0C90D47028}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{92BCA2A8-81C2-4572-8EE4-5244CEB2FA0B}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarksServerDotNetCore3", "BenchmarksServerDotNetCore3\BenchmarksServerDotNetCore3.csproj", "{F4DE9B2D-9850-40DB-B25C-6771567D69A6}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Console", "Console", "{B6CE174B-4020-42B7-97BD-014CC373694C}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetCore3", "DotnetCore3", "{F872A68D-58A4-4704-A801-28CAC5B8959A}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AddingNumbersInParallel", "AddingNumbersInParallel\AddingNumbersInParallel.csproj", "{94DC722C-D7A1-474E-B504-DBC615637494}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SortingStrategies", "SortingStrategies\SortingStrategies.csproj", "{3246BCC5-3AC2-4912-9EF3-C4871A7BA368}" 21 | EndProject 22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetFramework47", "DotnetFramework47", "{4EDFFED6-E555-442C-AB16-C019E439519E}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calculator", "Calculator\Calculator.csproj", "{4BBEF579-7C0B-4F02-A63C-2AB6C143593F}" 25 | EndProject 26 | Global 27 | GlobalSection(Performance) = preSolution 28 | HasPerformanceSessions = true 29 | EndGlobalSection 30 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 31 | Debug|Any CPU = Debug|Any CPU 32 | Release|Any CPU = Release|Any CPU 33 | EndGlobalSection 34 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 35 | {3A0132C6-FB69-4403-BCE9-C592371DEA7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {3A0132C6-FB69-4403-BCE9-C592371DEA7C}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {3A0132C6-FB69-4403-BCE9-C592371DEA7C}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {3A0132C6-FB69-4403-BCE9-C592371DEA7C}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {548832B4-08D3-4D7A-806A-FA0C90D47028}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {548832B4-08D3-4D7A-806A-FA0C90D47028}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {548832B4-08D3-4D7A-806A-FA0C90D47028}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {548832B4-08D3-4D7A-806A-FA0C90D47028}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {92BCA2A8-81C2-4572-8EE4-5244CEB2FA0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {92BCA2A8-81C2-4572-8EE4-5244CEB2FA0B}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {92BCA2A8-81C2-4572-8EE4-5244CEB2FA0B}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {92BCA2A8-81C2-4572-8EE4-5244CEB2FA0B}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {F4DE9B2D-9850-40DB-B25C-6771567D69A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 48 | {F4DE9B2D-9850-40DB-B25C-6771567D69A6}.Debug|Any CPU.Build.0 = Debug|Any CPU 49 | {F4DE9B2D-9850-40DB-B25C-6771567D69A6}.Release|Any CPU.ActiveCfg = Release|Any CPU 50 | {F4DE9B2D-9850-40DB-B25C-6771567D69A6}.Release|Any CPU.Build.0 = Release|Any CPU 51 | {94DC722C-D7A1-474E-B504-DBC615637494}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 52 | {94DC722C-D7A1-474E-B504-DBC615637494}.Debug|Any CPU.Build.0 = Debug|Any CPU 53 | {94DC722C-D7A1-474E-B504-DBC615637494}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {94DC722C-D7A1-474E-B504-DBC615637494}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {3246BCC5-3AC2-4912-9EF3-C4871A7BA368}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 56 | {3246BCC5-3AC2-4912-9EF3-C4871A7BA368}.Debug|Any CPU.Build.0 = Debug|Any CPU 57 | {3246BCC5-3AC2-4912-9EF3-C4871A7BA368}.Release|Any CPU.ActiveCfg = Release|Any CPU 58 | {3246BCC5-3AC2-4912-9EF3-C4871A7BA368}.Release|Any CPU.Build.0 = Release|Any CPU 59 | {4BBEF579-7C0B-4F02-A63C-2AB6C143593F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 60 | {4BBEF579-7C0B-4F02-A63C-2AB6C143593F}.Debug|Any CPU.Build.0 = Debug|Any CPU 61 | {4BBEF579-7C0B-4F02-A63C-2AB6C143593F}.Release|Any CPU.ActiveCfg = Release|Any CPU 62 | {4BBEF579-7C0B-4F02-A63C-2AB6C143593F}.Release|Any CPU.Build.0 = Release|Any CPU 63 | EndGlobalSection 64 | GlobalSection(SolutionProperties) = preSolution 65 | HideSolutionNode = FALSE 66 | EndGlobalSection 67 | GlobalSection(NestedProjects) = preSolution 68 | {F872A68D-58A4-4704-A801-28CAC5B8959A} = {B6CE174B-4020-42B7-97BD-014CC373694C} 69 | {94DC722C-D7A1-474E-B504-DBC615637494} = {F872A68D-58A4-4704-A801-28CAC5B8959A} 70 | {3246BCC5-3AC2-4912-9EF3-C4871A7BA368} = {F872A68D-58A4-4704-A801-28CAC5B8959A} 71 | {4EDFFED6-E555-442C-AB16-C019E439519E} = {B6CE174B-4020-42B7-97BD-014CC373694C} 72 | {4BBEF579-7C0B-4F02-A63C-2AB6C143593F} = {4EDFFED6-E555-442C-AB16-C019E439519E} 73 | EndGlobalSection 74 | GlobalSection(ExtensibilityGlobals) = postSolution 75 | SolutionGuid = {9E734F5B-9FA6-4F06-9322-210738A39328} 76 | EndGlobalSection 77 | EndGlobal 78 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using Serilog; 9 | 10 | namespace PracticalDebuggingDemos 11 | { 12 | /// 13 | /// Interaction logic for App.xaml 14 | /// 15 | public partial class App : Application 16 | { 17 | protected override void OnStartup(StartupEventArgs e) 18 | { 19 | Log.Logger = new LoggerConfiguration() 20 | .MinimumLevel.Debug() 21 | .WriteTo.File("Logs\\log.txt", rollingInterval: RollingInterval.Day) 22 | .CreateLogger(); 23 | AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 24 | 25 | base.OnStartup(e); 26 | } 27 | 28 | private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 29 | { 30 | Log.Fatal(e.ExceptionObject as Exception, $"Unhandled exception. IsTerminating: {e.IsTerminating}"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/DemoBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Threading.Tasks; 8 | 9 | namespace PracticalDebuggingDemos 10 | { 11 | public abstract class DemoBase : MVVMC.BaseViewModel 12 | { 13 | public virtual string Caption =>GetCaptionFromClassName(); 14 | 15 | protected string GetCaptionFromClassName() 16 | { 17 | var str = this.GetType().Name; 18 | return CamelCaseToFriendlyString(str); 19 | } 20 | 21 | private static string CamelCaseToFriendlyString(string str) 22 | { 23 | return Regex.Replace(str, "[a-z][A-Z]", m => $"{m.Value[0]} {char.ToLower(m.Value[1])}"); 24 | } 25 | 26 | public string Category => CamelCaseToFriendlyString(this.GetType().Namespace.Split('.').Last()); 27 | 28 | private object _content; 29 | public object Content 30 | { 31 | get { return _content; } 32 | set { _content = value; OnPropertyChanged();} 33 | } 34 | 35 | public void ClearContent() 36 | { 37 | Content = null; 38 | } 39 | 40 | 41 | public void AppendTextToContent(object text) 42 | { 43 | if (Content == null) 44 | Content = ""; 45 | Content = (string)Content + "\n" + text.ToString(); 46 | 47 | } 48 | 49 | public void AppendTextToContent(string format, object arg0) 50 | { 51 | AppendTextToContent(string.Format(format, arg0)); 52 | } 53 | 54 | public void AppendTextToContent(string format, object arg0, object arg1) 55 | { 56 | AppendTextToContent(string.Format(format, arg0, arg1)); 57 | } 58 | 59 | 60 | public abstract void Start(); 61 | 62 | public override string ToString() 63 | { 64 | return Caption; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Crashes/SimpleCrash.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.Crashes 8 | { 9 | public class SimpleCrash : DemoBase 10 | { 11 | public override void Start() 12 | { 13 | StartCalculation(15, 0); 14 | } 15 | 16 | private int StartCalculation(int a, int b) 17 | { 18 | int first = a; 19 | int second = b; 20 | return Divide(a, b); 21 | } 22 | 23 | private int Divide(int num1, int num2) 24 | { 25 | return num1 / num2; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Crashes/Tools/DebugWriteLine.cs: -------------------------------------------------------------------------------- 1 | using PracticalDebuggingDemos; 2 | using System; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace PracticalDebuggingDemos.Demos.Crashes.Tools 7 | { 8 | public class DebugWriteLine : DemoBase 9 | { 10 | public override void Start() 11 | { 12 | AppendTextToContent("Starting to write Debug.WriteLine()"); 13 | Task.Run(() => 14 | { 15 | while (true) 16 | { 17 | System.Diagnostics.Debug.WriteLine("Current time is: " + DateTime.Now.ToString()); 18 | Thread.Sleep(1000); 19 | } 20 | }); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Crashes/Tools/TraceWriteLine.cs: -------------------------------------------------------------------------------- 1 | using PracticalDebuggingDemos; 2 | using System; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace PracticalDebuggingDemos.Demos.Crashes.Tools 7 | { 8 | public class TraceWriteLine : DemoBase 9 | { 10 | public override void Start() 11 | { 12 | AppendTextToContent("Starting to write Trace.WriteLine()"); 13 | Task.Run(() => 14 | { 15 | while (true) 16 | { 17 | System.Diagnostics.Trace.WriteLine("Current time is: " + DateTime.Now.ToString()); 18 | Thread.Sleep(1000); 19 | } 20 | 21 | }); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Debug3rdPartyCode/NewtonsoftDeserialize.cs: -------------------------------------------------------------------------------- 1 | using PracticalDebuggingDemos.Demos.Models; 2 | 3 | namespace PracticalDebuggingDemos.Demos.Debug3rdPartyCode 4 | { 5 | public partial class NewtonsoftDeserialize : DemoBase 6 | { 7 | 8 | public override void Start() 9 | { 10 | var serialized = "{\"Nadsafsdfds"; 11 | Person deserialized = Newtonsoft.Json.JsonConvert.DeserializeObject(serialized); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Debug3rdPartyCode/NewtonsoftSerialize.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Debug3rdPartyCode 9 | { 10 | public class NewtonsoftSerialize : DemoBase 11 | { 12 | 13 | public override void Start() 14 | { 15 | var anon = new 16 | { 17 | Name = "Elon Musk", 18 | Companies = new string[] { "Tesla", "SpaceX", "PayPal" }, 19 | Age = 48 20 | }; 21 | var serialized = JsonConvert.SerializeObject(anon); 22 | AppendTextToContent(serialized); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Dumps/FirstChanceException.cs: -------------------------------------------------------------------------------- 1 | using PracticalDebuggingDemos; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Dumps 9 | { 10 | public class FirstChanceException : DemoBase 11 | { 12 | public override void Start() 13 | { 14 | string mystring = "1234,523"; 15 | Foo(mystring); 16 | } 17 | 18 | private void Foo(string mystring) 19 | { 20 | try 21 | { 22 | int parsed = Parse(mystring); 23 | AppendTextToContent("Convert succeeded " + parsed.ToString()); 24 | } 25 | catch (Exception ex) 26 | { 27 | AppendTextToContent("Parsing failed " + ex.ToString()); 28 | } 29 | } 30 | 31 | private int Parse(string mystring) 32 | { 33 | var result = int.Parse(mystring); 34 | return result; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Files/ReadOneFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Files 9 | { 10 | public class ReadOneFile : DemoBase 11 | { 12 | public override void Start() 13 | { 14 | var files = Directory.GetFiles(@"C:\Windows"); 15 | ReadFirstFile(files); 16 | AppendTextToContent("Finished"); 17 | } 18 | 19 | private void ReadFirstFile(string[] files) 20 | { 21 | var firstFile = files.First(); 22 | ReadFile(firstFile); 23 | } 24 | 25 | private void ReadFile(string file) 26 | { 27 | var lines = File.ReadAllLines(file); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/BeginInvokeFreeze.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Threading; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Freezes 9 | { 10 | public class BeginInvokeFreeze : DemoBase 11 | { 12 | public override void Start() 13 | { 14 | A(); 15 | } 16 | 17 | private void A() 18 | { 19 | Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => B())); 20 | } 21 | 22 | private void B() 23 | { 24 | Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => A())); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/CpuBoundFreeze.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.Freezes 8 | { 9 | public class CpuBoundFreeze : DemoBase 10 | { 11 | public override void Start() 12 | { 13 | while (true) 14 | { 15 | 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/DispatcherQueueDeadlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Threading; 8 | 9 | namespace PracticalDebuggingDemos.Demos.Freezes 10 | { 11 | public class DispatcherQueueDeadlock : DemoBase 12 | { 13 | public override void Start() 14 | { 15 | var dispatcher = Dispatcher.CurrentDispatcher; 16 | Task.Run(() => 17 | { 18 | Console.WriteLine("Long operation on another thread"); 19 | dispatcher.Invoke(() => 20 | { 21 | Application.Current.MainWindow.Title += "a"; 22 | //AppendTextToContent("inside dispatcher"); 23 | }); 24 | // This will occur on the UI Thread 25 | //MyTextBox.Text = "operation finished"); 26 | }).Wait(); 27 | Console.WriteLine("Do more stuff after the long operation is finished"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/DotResultDeadlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.Freezes 8 | { 9 | class DotResultDeadlock : DemoBase 10 | { 11 | public override void Start() 12 | { 13 | var x = Do().Result; 14 | } 15 | 16 | private async Task Do() 17 | { 18 | await Task.Delay(1000); 19 | return 5; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/DoubleNetstedDeadlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace PracticalDebuggingDemos.Demos.Freezes 10 | { 11 | public class DoubleNetstedDeadlock : DemoBase 12 | { 13 | public override void Start() 14 | { 15 | object lock1 = new object(); 16 | object lock2 = new object(); 17 | Debug.WriteLine("Starting..."); 18 | var task1 = Task.Run(() => 19 | { 20 | lock (lock1) 21 | { 22 | Debug.WriteLine("Entered lock1 in task1..."); 23 | Thread.Sleep(1000); 24 | lock (lock2) 25 | { 26 | Debug.WriteLine("Finished Thread 1"); 27 | } 28 | } 29 | }); 30 | 31 | var task2 = Task.Run(() => 32 | { 33 | lock (lock2) 34 | { 35 | Debug.WriteLine("Entered lock2 in task2..."); 36 | Thread.Sleep(1000); 37 | lock (lock1) 38 | { 39 | Debug.WriteLine("Finished Thread 2"); 40 | } 41 | } 42 | }); 43 | Task.WaitAll(task1, task2); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/IOBoundFreeze.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Net.Http; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace PracticalDebuggingDemos.Demos.Freezes 11 | { 12 | public class IOBoundFreeze : DemoBase 13 | { 14 | public override void Start() 15 | { 16 | var url = "http://localhost:60258/Home/LongRunning"; 17 | HttpWebRequest request = WebRequest.CreateHttp(url); 18 | request.Method = "GET"; 19 | using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 20 | { 21 | using (Stream responseStream = response.GetResponseStream()) 22 | { 23 | using (StreamReader myStreamReader = new StreamReader(responseStream, Encoding.UTF8)) 24 | { 25 | string res = myStreamReader.ReadToEnd(); 26 | } 27 | } 28 | } 29 | } 30 | 31 | public async Task AsyncStart() 32 | { 33 | var url = "http://localhost:60260/Home/LongRunning"; 34 | var client = new HttpClient(); 35 | var resp = await client.GetAsync(new Uri(url)).ConfigureAwait(false); 36 | var content = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/OddEven/OddEvenCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace PracticalDebuggingDemos.Demos.Freezes.OddEven 5 | { 6 | internal class OddEvenCounter 7 | { 8 | internal void Count(int[] array, out int numberOfOdds, out int numberOfEvens) 9 | { 10 | int odds = 0; 11 | int evens = 0; 12 | var oddTask = Task.Run(() => 13 | { 14 | odds = CountOdds(array); 15 | }); 16 | 17 | var evenTask = Task.Run(() => 18 | { 19 | evens = CountEvens(array); 20 | }); 21 | Task.WaitAll(oddTask, evenTask); 22 | numberOfEvens = evens; 23 | numberOfOdds = odds; 24 | } 25 | 26 | private int CountEvens(int[] array) 27 | { 28 | int index = 0; 29 | int count = 0; 30 | while (index < array.Length) 31 | { 32 | if (array[index] % 2 == 1) 33 | { 34 | continue; 35 | } 36 | else 37 | { 38 | count++; 39 | index++; 40 | } 41 | } 42 | return count; 43 | } 44 | 45 | private int CountOdds(int[] array) 46 | { 47 | int index = 0; 48 | int count = 0; 49 | while (index < array.Length) 50 | { 51 | if (array[index] % 2 == 0) 52 | { 53 | continue; 54 | } 55 | else 56 | { 57 | count++; 58 | index++; 59 | } 60 | } 61 | return count; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/OddEven/OddEvenMenu.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 12 | 15 | 18 | 21 | 22 | 23 | This will create a number of random numbers and then count Odds and Evens. 24 | Enter amount of numbers: 25 | 1000 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/OddEven/OddEvenMenu.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace PracticalDebuggingDemos.Demos.Freezes.OddEven 17 | { 18 | /// 19 | /// Interaction logic for OddEvenMenu.xaml 20 | /// 21 | public partial class OddEvenMenu : UserControl 22 | { 23 | public OddEvenMenu() 24 | { 25 | InitializeComponent(); 26 | } 27 | 28 | private void StartCount(object sender, RoutedEventArgs e) 29 | { 30 | var numbers = int.Parse(numItems.Text); 31 | var rnd = new Random(); 32 | var array = Enumerable.Range(0, numbers).Select(x => rnd.Next()).ToArray(); 33 | var counter = new OddEvenCounter(); 34 | counter.Count(array, out int numberOfOdds, out int numberOfEvens); 35 | resultTextBlock.Text = $"Odds: {numberOfOdds} and evens: {numberOfEvens}"; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Freezes/OddEvenFreeze.cs: -------------------------------------------------------------------------------- 1 | using PracticalDebuggingDemos.Demos.Freezes.OddEven; 2 | 3 | namespace PracticalDebuggingDemos.Demos.Freezes 4 | { 5 | public class OddEvenFreeze : DemoBase 6 | { 7 | public override void Start() 8 | { 9 | Content = new OddEvenMenu(); 10 | } 11 | } 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/EndlessMemory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Memory 9 | { 10 | public class ValuesHolder 11 | { 12 | public ValuesHolder() 13 | { 14 | 15 | } 16 | public List Values { get; set; } = new List(); 17 | } 18 | 19 | public class EndlessMemory : DemoBase 20 | { 21 | public static ValuesHolder ValuesHolder = new ValuesHolder(); 22 | private static Random rnd = new Random(); 23 | 24 | public override void Start() 25 | { 26 | try 27 | { 28 | ClearContent(); 29 | AppendTextToContent("Start calculating..."); 30 | Task.Run((Action)Calc).ContinueWith((s) => 31 | { 32 | var mean = GetMean(); 33 | AppendTextToContent($"Mean is: {mean}"); 34 | }, TaskScheduler.FromCurrentSynchronizationContext()); 35 | 36 | 37 | } 38 | catch (Exception e) 39 | { 40 | AppendTextToContent(e); 41 | AppendTextToContent("Program can keep running"); 42 | } 43 | 44 | } 45 | 46 | private void Calc() 47 | { 48 | for (int i = 0; i < 1000; i++) 49 | { 50 | ValuesHolder.Values.Add(GetData()); 51 | Thread.Sleep(2); 52 | 53 | } 54 | } 55 | 56 | private Double[] GetData() 57 | { 58 | List values = new List(); 59 | 60 | for (long ctr = 1; ctr <= 10000; ctr++) 61 | { 62 | values.Add(rnd.NextDouble()); 63 | } 64 | return values.ToArray(); 65 | } 66 | 67 | private static Double GetMean() 68 | { 69 | int count = 0; 70 | Double sum = 0; 71 | foreach (var numbers in ValuesHolder.Values) 72 | { 73 | foreach (var num in numbers) 74 | { 75 | count++; 76 | sum += num; 77 | } 78 | } 79 | 80 | return sum / count; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/EndlessMemory2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.Memory 8 | { 9 | //public class EndlessMemory2 : DemoBase 10 | //{ 11 | // public static List big= new List(); 12 | 13 | // public override void Start() 14 | // { 15 | // try 16 | // { 17 | // List wastedMemory = new List(); 18 | 19 | // while(true) 20 | // { 21 | // byte[] buffer = new byte[4096]; // Allocate 4kb 22 | // wastedMemory.Add(buffer); 23 | // } 24 | 25 | // } 26 | // catch (Exception e) 27 | // { 28 | // AppendTextToContent(e); 29 | // AppendTextToContent("Program can keep running"); 30 | // } 31 | 32 | // } 33 | 34 | 35 | 36 | //} 37 | } 38 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/ManyAllocationsGCPressureGen0Pressure.cs: -------------------------------------------------------------------------------- 1 | using PracticalDebuggingDemos; 2 | using PracticalDebuggingDemos.Demos.Models; 3 | using System.Threading.Tasks; 4 | 5 | namespace PracticalDebuggingDemos.Demos.Memory 6 | { 7 | public class ManyAllocationsGCPressureGen0Pressure : DemoBase 8 | { 9 | /// 10 | /// In this test, there's constant allocations of short-lived objects on 5 threads. 11 | /// Even though there's non-stop allocations, GC pressure isn't created. 12 | /// You'll see the performance counter "% Time in GC" rise to be around a fixed range - maybe 10 to 20%. 13 | /// Decreasing the threads to 1 thread will reduce it even more. 14 | /// 15 | public override void Start() 16 | { 17 | for (int i = 0; i < 5; i++) 18 | { 19 | Task.Run(() => 20 | { 21 | while (true) 22 | { 23 | var person = new Person() 24 | { 25 | Age = 1242, 26 | Name = "Bill Gates" 27 | }; 28 | } 29 | }); 30 | } 31 | 32 | 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/ManyAllocationsGCPressureGen1Pressure.cs: -------------------------------------------------------------------------------- 1 | using PracticalDebuggingDemos.Demos.Models; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace PracticalDebuggingDemos.Demos.Memory 7 | { 8 | public class ManyAllocationsGCPressureGen1Pressure : DemoBase 9 | { 10 | static List listStatic; 11 | 12 | public override void Start() 13 | { 14 | Task.Run(() => 15 | { 16 | while (true) 17 | { 18 | List list = new List(); 19 | for (int i = 0; i < 12000; i++) 20 | { 21 | 22 | var person = new Person() 23 | { 24 | Age = 1242, 25 | Name = "Bill Gates" 26 | }; 27 | list.Add(person); 28 | } 29 | Task.Run(() => 30 | { 31 | Thread.Sleep(1000); 32 | var list2 = list; 33 | listStatic = list2; 34 | }); 35 | } 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/MemoryExceeds2GB.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.Memory 8 | { 9 | public class MemoryExceeds2Gb : DemoBase 10 | { 11 | public override void Start() 12 | { 13 | try 14 | { 15 | Double[] values = GetData(); 16 | // Compute mean. 17 | AppendTextToContent("Sample mean: {0}, N = {1}", 18 | GetMean(values), values.Length); 19 | } 20 | catch (Exception e) 21 | { 22 | AppendTextToContent(e); 23 | AppendTextToContent("Program can keep running"); 24 | } 25 | 26 | } 27 | 28 | 29 | 30 | private Double[] GetData() 31 | { 32 | Random rnd = new Random(); 33 | List values = new List(); 34 | for (int ctr = 1; ctr <= 200000000; ctr++) { 35 | values.Add(rnd.NextDouble()); 36 | if (ctr % 10000000 == 0) 37 | AppendTextToContent("Retrieved {0:N0} items of data.", 38 | ctr); 39 | } 40 | return values.ToArray(); 41 | } 42 | 43 | private static Double GetMean(Double[] values) 44 | { 45 | Double sum = 0; 46 | foreach (var value in values) 47 | sum += value; 48 | 49 | return sum / values.Length; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/StockMarketMemoryLeak.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PracticalDebuggingDemos.Demos.Memory 4 | { 5 | 6 | 7 | public class StockMarketMemoryLeak : DemoBase 8 | { 9 | public static StockMarketManager Manager = new StockMarketManager(); 10 | public override void Start() 11 | { 12 | var actionWindow = new StockMarketWindow(Manager); 13 | actionWindow.Show(); 14 | } 15 | } 16 | 17 | 18 | public class StockMarketManager 19 | { 20 | public event Action StockChanged; 21 | } 22 | 23 | public class StockChangeEvent 24 | { 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/StockMarketWindow.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/StockMarketWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using System.Windows; 3 | 4 | namespace PracticalDebuggingDemos.Demos.Memory 5 | { 6 | 7 | public class Stock 8 | { 9 | public string Name { get; set; } 10 | public double Price { get; set; } 11 | public bool IsUp { get; set; } 12 | } 13 | /// 14 | /// Interaction logic for StockActionWindow.xaml 15 | /// 16 | public partial class StockMarketWindow : Window 17 | { 18 | public StockMarketWindow(StockMarketManager manager) 19 | { 20 | manager.StockChanged += OnStockChanged; 21 | 22 | Stocks = new ObservableCollection(); 23 | Stocks.Add(new Stock() 24 | { 25 | Name = "Tesla", 26 | Price = 750, 27 | IsUp = false, 28 | }); 29 | Stocks.Add(new Stock() 30 | { 31 | Name = "Microsoft", 32 | Price = 183, 33 | IsUp = true, 34 | }); 35 | Stocks.Add(new Stock() 36 | { 37 | Name = "Intel", 38 | Price = 183, 39 | IsUp = true, 40 | }); 41 | Stocks.Add(new Stock() 42 | { 43 | Name = "ALPHABET", 44 | Price = 66, 45 | IsUp = true, 46 | }); 47 | Stocks.Add(new Stock() 48 | { 49 | Name = "Oracle", 50 | Price = 54, 51 | IsUp = false, 52 | 53 | }); 54 | Stocks.Add(new Stock() 55 | { 56 | Name = "Apple", 57 | Price = 320, 58 | IsUp = true, 59 | }); 60 | InitializeComponent(); 61 | } 62 | 63 | private void OnStockChanged(StockChangeEvent obj) 64 | { 65 | } 66 | 67 | public ObservableCollection Stocks 68 | { 69 | get { return (ObservableCollection )GetValue(StocksProperty); } 70 | set { SetValue(StocksProperty, value); } 71 | } 72 | public static readonly DependencyProperty StocksProperty = 73 | DependencyProperty.Register("Stocks", typeof(ObservableCollection ), typeof(StockMarketWindow), new PropertyMetadata()); 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/StringBuilderFewStrings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.Memory 8 | { 9 | public class StringBuilderFewStrings : DemoBase 10 | { 11 | public override void Start() 12 | { 13 | 14 | } 15 | 16 | 17 | static string A = "asd"; 18 | static string B = "fgh"; 19 | static string C = "qwer"; 20 | static string D = "tyuuiop"; 21 | 22 | private static string s; 23 | 24 | 25 | public void ExecuteA() 26 | { 27 | s = A + B + C + D; 28 | } 29 | 30 | public void ExecuteB() 31 | { 32 | StringBuilder sb = new StringBuilder(A); 33 | sb.Append(B); 34 | sb.Append(C); 35 | sb.Append(D); 36 | s = sb.ToString(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/StringBuilderOutOfMemory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.Memory 8 | { 9 | public class StringBuilderOutOfMemory : DemoBase 10 | { 11 | public override void Start() 12 | { 13 | StringBuilder sb = new StringBuilder(15, 15); 14 | sb.Append("Substring #1 "); 15 | try { 16 | sb.Insert(0, "Substring #2 ", 1); 17 | } 18 | catch (OutOfMemoryException e) { 19 | AppendTextToContent("Out of Memory: {0}", e.Message); 20 | } 21 | 22 | AppendTextToContent("OutOfMemoryException thrown and program keeps running"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Memory/TimerMemoryLeak.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using System.Timers; 9 | using Timer = System.Threading.Timer; 10 | 11 | namespace PracticalDebuggingDemos.Demos.Memory 12 | { 13 | public class TimerMemoryLeak : DemoBase 14 | { 15 | public class MyClass 16 | { 17 | private readonly DemoBase _demoBase; 18 | 19 | public MyClass(DemoBase demoBase) 20 | { 21 | _demoBase = demoBase; 22 | Timer timer = new Timer(HandleTick); 23 | timer.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2)); 24 | } 25 | 26 | private void HandleTick(object state) 27 | { 28 | _demoBase.AppendTextToContent("Tick"); 29 | Debug.WriteLine("Tick"); 30 | } 31 | } 32 | 33 | public override void Start() 34 | { 35 | new MyClass(this); 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Misc/Break.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Misc 9 | { 10 | public class Break : DemoBase 11 | { 12 | public override void Start() 13 | { 14 | Debugger.Break(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Models/Person.cs: -------------------------------------------------------------------------------- 1 | namespace PracticalDebuggingDemos.Demos.Models 2 | { 3 | public class Person 4 | { 5 | public string Name { get; set; } 6 | public int Age { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/AddInParallel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace PracticalDebuggingDemos.Demos.Performance 10 | { 11 | class AddInParallel : DemoBase 12 | { 13 | private static object _lock = new object(); 14 | 15 | public override void Start() 16 | { 17 | int numbers = 500_500_000; 18 | AppendTextToContent($"Adding {numbers} in parallel."); 19 | Stopwatch sw = new Stopwatch(); 20 | int sum = 0; 21 | Task.Run(() => 22 | { 23 | //var numbersArr = CreateArray(numbers); 24 | sw.Start(); 25 | sum = SumParallel(numbers); //SumSimple(numbersArr);// 26 | sw.Stop(); 27 | }).ContinueWith((t) => 28 | { 29 | AppendTextToContent($"Finished in {sw.Elapsed.TotalSeconds} seconds. SumParallel = {sum}"); 30 | }, TaskScheduler.FromCurrentSynchronizationContext()); 31 | 32 | 33 | } 34 | 35 | private static int[] CreateArray(int numbers) 36 | { 37 | return Enumerable.Range(0, numbers).Reverse().ToArray(); 38 | } 39 | 40 | static int SumParallel(int items) 41 | { 42 | int total = 0; 43 | int threads = Math.Min(items, 8); 44 | var partSize = Math.Round(items / (double)threads + 0.5); 45 | Task[] tasks = new Task[threads]; 46 | for (int iThread = 0; iThread < threads; iThread++) 47 | { 48 | var localThread = iThread; 49 | tasks[localThread] = Task.Run(() => 50 | { 51 | var to = Math.Min(items, Math.Round((localThread + 1) * partSize + 0.5)); 52 | for (int j = (int)(localThread * partSize); j < to; j++) 53 | { 54 | lock (_lock) 55 | { 56 | total += j; 57 | } 58 | } 59 | }); 60 | } 61 | 62 | Task.WaitAll(tasks); 63 | //var verifySum = arr.SumParallel(); 64 | return total; 65 | } 66 | 67 | static int SumSimple(int items) 68 | { 69 | int sum = 0; 70 | for (int i = 0; i < items; i++) 71 | { 72 | sum += i; 73 | } 74 | 75 | return sum; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/CountPrimes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | namespace PracticalDebuggingDemos.Demos.Performance 11 | { 12 | class CountPrimes : DemoBase 13 | { 14 | public override void Start() 15 | { 16 | int number = 1000; 17 | AppendTextToContent($"Checking how many prime numbers exist between 2 and {number}."); 18 | Stopwatch sw = new Stopwatch(); 19 | int sum = 0; 20 | Task.Run(() => 21 | { 22 | sw.Start(); 23 | sum = HowManyPrimes(number); 24 | sw.Stop(); 25 | return sum; 26 | }).ContinueWith((t) => 27 | { 28 | AppendTextToContent($"There are {t.Result} primes from 2 to {number}"); 29 | AppendTextToContent($"Finished within {sw.Elapsed.TotalSeconds} seconds."); 30 | }, TaskScheduler.FromCurrentSynchronizationContext()); 31 | 32 | 33 | } 34 | 35 | private int HowManyPrimes(int number) 36 | { 37 | int count = 0; 38 | for (int num = 2; num <= number; num++) 39 | { 40 | if (IsPrime(num)) 41 | { 42 | count++; 43 | } 44 | } 45 | return count; 46 | } 47 | 48 | private bool IsPrime(int num) 49 | { 50 | for (int i = 2; i < num; i++) 51 | { 52 | if (num % i == 0) 53 | { 54 | Thread.Sleep(5); 55 | return false; 56 | } 57 | } 58 | return true; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/LongAsyncNetworkRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Net.Http; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace PracticalDebuggingDemos.Demos.Performance 12 | { 13 | class LongAsyncNetworkRequest : DemoBase 14 | { 15 | public override void Start() 16 | { 17 | var url = "http://localhost:60260/Home/LongRunning";//"https://edition.cnn.com/"; 18 | var sw = new Stopwatch(); 19 | AppendTextToContent("Starting"); 20 | sw.Start(); 21 | Task.Run(async () => 22 | { 23 | while (sw.Elapsed.TotalSeconds < 5) 24 | { 25 | await GetAndCountInfo(url).ConfigureAwait(false); 26 | } 27 | }).ContinueWith((s) => { 28 | 29 | AppendTextToContent("Finished"); 30 | }, TaskScheduler.FromCurrentSynchronizationContext()); 31 | } 32 | 33 | private async Task GetAndCountInfo(string url) //Executes on UI threads 34 | { 35 | var client = new HttpClient(); 36 | var resp = await client.GetAsync(new Uri(url)).ConfigureAwait(false); 37 | var content = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); 38 | return content.Length; 39 | } 40 | 41 | private static void SyncWebRequest(string url) 42 | { 43 | HttpWebRequest request = WebRequest.CreateHttp(url); 44 | request.Method = "GET"; // or "POST", "PUT", "PATCH", "DELETE", etc. 45 | using (HttpWebResponse response = (HttpWebResponse) request.GetResponse()) 46 | { 47 | using (Stream responseStream = response.GetResponseStream()) 48 | { 49 | // Get a reader capable of reading the response stream 50 | using (StreamReader myStreamReader = new StreamReader(responseStream, Encoding.UTF8)) 51 | { 52 | // Read stream content as string 53 | string responseJSON = myStreamReader.ReadToEnd(); 54 | 55 | // Assuming the response is in JSON format, deserialize it 56 | // creating an instance of TData type (generic type declared before). 57 | //data = JsonConvert.DeserializeObject(responseJSON); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/LongSynchronousFileRead.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Net.Http; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace PracticalDebuggingDemos.Demos.Performance 12 | { 13 | class LongSynchronousFileRead : DemoBase 14 | { 15 | public override void Start() 16 | { 17 | var file = @"C:\Windows\System32\mspaint.exe"; 18 | var sw = new Stopwatch(); 19 | sw.Start(); 20 | 21 | while (sw.Elapsed.TotalSeconds < 20) 22 | { 23 | ReadFileSync(file); 24 | //WithHttpClient(url).GetAwaiter().GetResult(); 25 | 26 | } 27 | } 28 | 29 | private void ReadFileSync(string file) 30 | { 31 | var str = File.ReadAllText(file); 32 | } 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/LongSynchronousNetworkRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Net.Http; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace PracticalDebuggingDemos.Demos.Performance 12 | { 13 | class LongSynchronousNetworkRequest : DemoBase 14 | { 15 | public override void Start() 16 | { 17 | var url = "https://edition.cnn.com/"; 18 | var sw = new Stopwatch(); 19 | sw.Start(); 20 | 21 | while (sw.Elapsed.TotalSeconds < 20) 22 | { 23 | SyncWebRequest(url); 24 | } 25 | } 26 | 27 | private async Task GetAndCountInfo(string url) //Executes on UI threads 28 | { 29 | var client = new HttpClient(); 30 | var resp = await client.GetAsync(new Uri(url)).ConfigureAwait(false); 31 | var content = await resp.Content.ReadAsStringAsync().ConfigureAwait(false); 32 | return content.Length; 33 | } 34 | 35 | private static void SyncWebRequest(string url) 36 | { 37 | HttpWebRequest request = WebRequest.CreateHttp(url); 38 | request.Method = "GET"; // or "POST", "PUT", "PATCH", "DELETE", etc. 39 | using (HttpWebResponse response = (HttpWebResponse) request.GetResponse()) 40 | { 41 | using (Stream responseStream = response.GetResponseStream()) 42 | { 43 | // Get a reader capable of reading the response stream 44 | using (StreamReader myStreamReader = new StreamReader(responseStream, Encoding.UTF8)) 45 | { 46 | // Read stream content as string 47 | string responseJSON = myStreamReader.ReadToEnd(); 48 | 49 | // Assuming the response is in JSON format, deserialize it 50 | // creating an instance of TData type (generic type declared before). 51 | //data = JsonConvert.DeserializeObject(responseJSON); 52 | } 53 | } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/ManyExceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Performance 9 | { 10 | public class ManyExceptions : DemoBase 11 | { 12 | public override void Start() 13 | { 14 | var array = new string[] 15 | { "1", "a", "2", "sdf1", "5", "b", "b", "6", "7", "y" }; 16 | var times = 100_000; 17 | Stopwatch sw = new Stopwatch(); 18 | AppendTextToContent("Starting..."); 19 | sw.Start(); 20 | for (int i = 0; i < times; i++) 21 | { 22 | ParseWithPossibleException(array); 23 | } 24 | sw.Stop(); 25 | AppendTextToContent($"Finished {times} times withing {sw.Elapsed.TotalSeconds} seconds."); 26 | } 27 | 28 | public void ParseWithPossibleException(string[] arr) 29 | { 30 | int count = 0; 31 | foreach (var item in arr) 32 | { 33 | try 34 | { 35 | var casted = int.Parse(item); 36 | count += casted; 37 | } 38 | catch { } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/Sorting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using PracticalDebuggingDemos.Demos.CPUBound; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Performance 9 | { 10 | public class Sorting : DemoBase 11 | { 12 | public override void Start() 13 | { 14 | Content = new SortingMenu(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/Sorting/Bubble.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.CPUBound 8 | { 9 | public class Bubble : ISortingStrategy 10 | { 11 | public void Sort(int[] data) 12 | { 13 | int i, j; 14 | int N = data.Length; 15 | 16 | for (j = N - 1; j > 0; j--) 17 | { 18 | for (i = 0; i < j; i++) 19 | { 20 | if (data[i] > data[i + 1]) 21 | exchange(data, i, i + 1); 22 | } 23 | } 24 | 25 | } 26 | 27 | public static void exchange (int[] data, int m, int n) 28 | { 29 | int temporary; 30 | 31 | temporary = data [m]; 32 | data [m] = data [n]; 33 | data [n] = temporary; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/Sorting/ISortingStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace PracticalDebuggingDemos.Demos.CPUBound 2 | { 3 | public interface ISortingStrategy 4 | { 5 | void Sort(int[] items); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/Sorting/QuickSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace PracticalDebuggingDemos.Demos.CPUBound 10 | { 11 | public class QuickSort : ISortingStrategy 12 | { 13 | private DateTime _startTime; 14 | private int _countOperations; 15 | 16 | public void Sort(int[] data) 17 | { 18 | _startTime = DateTime.Now; 19 | _countOperations = 0; 20 | Quick_Sort(data, 0, data.Length - 1); 21 | } 22 | 23 | private void Quick_Sort(int[] arr, int left, int right) 24 | { 25 | _countOperations++; 26 | if (_countOperations % 50 == 0) 27 | { 28 | WriteLog($"Time elapsed seconds: {(DateTime.Now - _startTime).TotalSeconds}"); 29 | } 30 | 31 | if (left < right) 32 | { 33 | int pivot = Partition(arr, left, right); 34 | 35 | if (pivot > 1) { 36 | Quick_Sort(arr, left, pivot - 1); 37 | } 38 | if (pivot + 1 < right) { 39 | Quick_Sort(arr, pivot + 1, right); 40 | } 41 | } 42 | 43 | } 44 | 45 | private void WriteLog(string msg) 46 | { 47 | var file = Path.GetTempPath() + @"\PracticalDebugging\quick_sort.txt"; 48 | File.AppendAllLines(file, new string[] { msg }); 49 | } 50 | 51 | private int Partition(int[] arr, int left, int right) 52 | { 53 | int pivot = arr[left]; 54 | while (true) 55 | { 56 | 57 | while (arr[left] < pivot) 58 | { 59 | left++; 60 | } 61 | 62 | while (arr[right] > pivot) 63 | { 64 | right--; 65 | } 66 | 67 | if (left < right) 68 | { 69 | if (arr[left] == arr[right]) return right; 70 | 71 | int temp = arr[left]; 72 | arr[left] = arr[right]; 73 | arr[right] = temp; 74 | 75 | 76 | } 77 | else 78 | { 79 | return right; 80 | } 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/Sorting/SortingMenu.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 13 | 16 | 19 | 22 | 23 | 24 | Sorting strategy: 25 | 26 | 27 | Bubble 28 | Quick Sort 29 | 30 | 31 | Items: 32 | 30000 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/Sorting/SortingMenu.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Navigation; 15 | using System.Windows.Shapes; 16 | 17 | namespace PracticalDebuggingDemos.Demos.CPUBound 18 | { 19 | /// 20 | /// Interaction logic for SortingMenu.xaml 21 | /// 22 | public partial class SortingMenu : UserControl 23 | { 24 | public SortingMenu() 25 | { 26 | InitializeComponent(); 27 | } 28 | 29 | private void StartSorting(object sender, RoutedEventArgs e) 30 | { 31 | var strategy = GetSortingStrategy(); 32 | var items = GetItems(); 33 | 34 | Stopwatch sw = new Stopwatch(); 35 | sw.Start(); 36 | strategy.Sort(items); 37 | sw.Stop(); 38 | resultTextBlock.Text = "Finished. Operation time in seconds: " + sw.Elapsed.TotalSeconds; 39 | } 40 | 41 | private ISortingStrategy GetSortingStrategy() 42 | { 43 | ISortingStrategy s; 44 | switch (sortStrategy.Text) 45 | { 46 | case "Quick Sort": 47 | s = new QuickSort(); 48 | break; 49 | case "Bubble": 50 | default: 51 | s = new Bubble(); 52 | break; 53 | } 54 | 55 | return s; 56 | } 57 | 58 | private int[] GetItems() 59 | { 60 | int[] res = new int[int.Parse(numItems.Text)]; 61 | Random rnd = new Random(); 62 | for (int i = 0; i < res.Length; i++) 63 | { 64 | res[i] = rnd.Next(); 65 | } 66 | 67 | return res; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/ThreadsWaiting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Performance 9 | { 10 | class ThreadsWaiting : DemoBase 11 | { 12 | public override void Start() 13 | { 14 | object lock1 = new object(); 15 | AppendTextToContent("Started"); 16 | 17 | var task1 = Task.Run(() => { ThreadOperation(lock1, "Thread A"); }); 18 | var task2 = Task.Run(() => { ThreadOperation(lock1, "Thread B"); }); 19 | Task.WhenAll(task1, task2).ContinueWith((t) => 20 | { 21 | AppendTextToContent("Finished"); 22 | }, TaskScheduler.FromCurrentSynchronizationContext()); 23 | } 24 | 25 | private void ThreadOperation(object lock1, string threadName) 26 | { 27 | for (int i = 0; i < 10; i++) 28 | { 29 | lock (lock1) 30 | { 31 | AppendTextToContent($"{threadName} is running iteration {i}"); 32 | Thread.Sleep(5000); 33 | } 34 | } 35 | 36 | 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/Performance/ThreadsWaitingAutoResetEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.Performance 9 | { 10 | class ThreadsWaitingAutoResetEvent : DemoBase 11 | { 12 | private AutoResetEvent _are; 13 | 14 | public override void Start() 15 | { 16 | AppendTextToContent("Started"); 17 | _are = new AutoResetEvent(true); 18 | var task1 = Task.Run(() => { ThreadOperation("Thread A"); }); 19 | var task2 = Task.Run(() => { ThreadOperation("Thread B"); }); 20 | Task.WhenAll(task1, task2).ContinueWith((t) => 21 | { 22 | AppendTextToContent("Finished"); 23 | }, TaskScheduler.FromCurrentSynchronizationContext()); 24 | } 25 | 26 | private void ThreadOperation(string threadName) 27 | { 28 | for (int i = 0; i < 10; i++) 29 | { 30 | _are.WaitOne(); 31 | { 32 | System.Diagnostics.Debug.WriteLine($"{threadName} is running iteration {i}"); 33 | Thread.Sleep(2000); 34 | } 35 | _are.Set(); 36 | } 37 | 38 | 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/PerformanceCountersConsume/PerformanceCountersConsume.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using System.Windows.Controls; 9 | 10 | namespace PracticalDebuggingDemos.Demos.PerformanceCountersThreeCPUThreads.PerformanceCountersConsume 11 | { 12 | public class PerformanceCountersConsume : DemoBase 13 | { 14 | public override void Start() 15 | { 16 | ConsumeCounters(); 17 | 18 | //CreateCustomCounter(); 19 | } 20 | 21 | private void ConsumeCounters() 22 | { 23 | var currentProcess = Process.GetCurrentProcess().ProcessName; 24 | PerformanceCounter privateBytes = 25 | new PerformanceCounter(categoryName: "Process", counterName: "Private Bytes", instanceName: currentProcess); 26 | PerformanceCounter gen2Collections = 27 | new PerformanceCounter(categoryName: ".NET CLR Memory", counterName: "# Gen 2 Collections", instanceName: currentProcess); 28 | 29 | Debug.WriteLine("private bytes = " + privateBytes.NextValue()); 30 | Debug.WriteLine("gen 2 collections = " + gen2Collections.NextValue()); 31 | 32 | Content = "private bytes = " + privateBytes.NextValue() + "\n" + "gen 2 collections = " + gen2Collections.NextValue(); 33 | } 34 | 35 | private void CreateCustomCounter() 36 | { 37 | bool exists = PerformanceCounterCategory.Exists("MyTimeCategory"); 38 | if (!exists) 39 | { 40 | PerformanceCounterCategory.Create("MyTimeCategory", "My category help", 41 | PerformanceCounterCategoryType.SingleInstance, "Current Seconds", 42 | "My counter help"); 43 | } 44 | 45 | PerformanceCounter pc = new PerformanceCounter("MyTimeCategory", "Current Seconds", false); 46 | while (true) 47 | { 48 | Thread.Sleep(1000); 49 | pc.RawValue = DateTime.Now.Second; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/PerformanceCountersThreeCpuThreads/PerformanceCountersThreeCPUThreads.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | namespace PracticalDebuggingDemos.Demos.PerformanceCounters 4 | { 5 | public class PerformanceCountersThreeCpuThreads : DemoBase 6 | { 7 | 8 | public override void Start() 9 | { 10 | ThreadPool.QueueUserWorkItem((s) => DoCpuWork()); 11 | ThreadPool.QueueUserWorkItem((s) => DoCpuWork()); 12 | ThreadPool.QueueUserWorkItem((s) => DoCpuWork()); 13 | } 14 | 15 | private void DoCpuWork() 16 | { 17 | long count = 0; 18 | while (true) 19 | { 20 | count += 5; 21 | count = count & long.MaxValue; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/VisualStudio/MultiThreadedCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace PracticalDebuggingDemos.Demos.VisualStudio 9 | { 10 | public class MultiThreadedCounter : DemoBase 11 | { 12 | private int _counter; 13 | 14 | public override void Start() 15 | { 16 | _counter = 1; 17 | Task.Run((Action)IncreaseCounter); 18 | Task.Run((Action)DoubleCounter); 19 | Task.Run((Action)LogCounter); 20 | 21 | } 22 | 23 | private void IncreaseCounter() 24 | { 25 | while (true) 26 | { 27 | Interlocked.Add(ref _counter, 1); 28 | Thread.Sleep(15); 29 | } 30 | } 31 | 32 | private void DoubleCounter() 33 | { 34 | while (true) 35 | { 36 | var counterNow = _counter; 37 | Interlocked.Add(ref _counter, counterNow); 38 | Thread.Sleep(200); 39 | } 40 | } 41 | 42 | private void LogCounter() 43 | { 44 | while (true) 45 | { 46 | AppendTextToContent($"Counter: {_counter}"); 47 | Thread.Sleep(500); 48 | } 49 | } 50 | 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/Demos/VisualStudio/ParallelWatchExample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PracticalDebuggingDemos.Demos.VisualStudio 8 | { 9 | public class ParallelWatchExample : DemoBase 10 | { 11 | public override void Start() 12 | { 13 | for (int i = 0; i < 6; i++) 14 | { 15 | var localIndex = i; 16 | Task.Run(() => StartCalculating(localIndex)); 17 | } 18 | } 19 | 20 | private void StartCalculating(int i) 21 | { 22 | int count = 0; 23 | while (true) 24 | { 25 | count += i; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Data; 10 | using System.Windows.Input; 11 | using MVVMC; 12 | using Serilog; 13 | 14 | namespace PracticalDebuggingDemos 15 | { 16 | public class MainViewModel : MVVMC.BaseViewModel 17 | { 18 | public ObservableCollection Demos { get; } = new ObservableCollection(); 19 | public ListCollectionView _allDemos; 20 | 21 | public ListCollectionView AllDemos 22 | { 23 | get { return _allDemos; } 24 | set 25 | { 26 | _allDemos = value; 27 | OnPropertyChanged(); 28 | } 29 | } 30 | 31 | 32 | 33 | public MainViewModel() 34 | { 35 | Log.Information("Starting MainViewModel"); 36 | PopulateComboBox(); 37 | } 38 | 39 | DemoBase _selectedDemo; 40 | public DemoBase SelectedDemo 41 | { 42 | get { return _selectedDemo; } 43 | set 44 | { 45 | _selectedDemo = value; 46 | OnPropertyChanged(); 47 | } 48 | } 49 | DemoBase _activeDemo; 50 | public DemoBase ActiveDemo 51 | { 52 | get { return _activeDemo; } 53 | set 54 | { 55 | _activeDemo = value; 56 | OnPropertyChanged(); 57 | } 58 | } 59 | 60 | //public object _content; 61 | //public object Content 62 | //{ 63 | // get { return _content; } 64 | // set { _content = value; OnPropertyChanged(); } 65 | //} 66 | 67 | public ICommand _goCommand; 68 | public ICommand GoCommand 69 | { 70 | get 71 | { 72 | if (_goCommand == null) 73 | { 74 | _goCommand = new DelegateCommand(() => 75 | { 76 | SelectedDemo.ClearContent(); 77 | SelectedDemo.Start(); 78 | ActiveDemo = SelectedDemo; 79 | }); 80 | } 81 | return _goCommand; 82 | } 83 | } 84 | 85 | private void PopulateComboBox() 86 | { 87 | var demos = Assembly.GetExecutingAssembly().GetTypes().Where(type => type.BaseType == typeof(DemoBase)) 88 | .ToList(); 89 | foreach (var demo in demos) 90 | { 91 | Demos.Add(Activator.CreateInstance(demo) as DemoBase); 92 | } 93 | 94 | AllDemos = new ListCollectionView(Demos); 95 | AllDemos.GroupDescriptions.Add(new PropertyGroupDescription(nameof(DemoBase.Category))); 96 | } 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /PracticalDebugingDemos/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Choose: 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |