diff --git a/docs/csharp/distinguish-delegates-events.md b/docs/csharp/distinguish-delegates-events.md index a7292c414344a..c4b0e4612f4cc 100644 --- a/docs/csharp/distinguish-delegates-events.md +++ b/docs/csharp/distinguish-delegates-events.md @@ -48,7 +48,7 @@ properly sort the elements. LINQ queries must be supplied with delegates in order to determine what elements to return. Both used a design built with delegates. -Consider the `OnProgress` event handler. It reports progress on a task. +Consider the `Progress` event. It reports progress on a task. The task continues to proceed whether or not there are any listeners. The `FileSearcher` is another example. It would still search and find all the files that were sought, even with no event subscribers attached. diff --git a/docs/csharp/event-pattern.md b/docs/csharp/event-pattern.md index 29cd83ae2fc69..831896cdd9a11 100644 --- a/docs/csharp/event-pattern.md +++ b/docs/csharp/event-pattern.md @@ -29,7 +29,7 @@ subscribe and process standard events in your code. The standard signature for a .NET event delegate is: ```cs -void Handler(object sender, EventArgs args); +void OnEventRaised(object sender, EventArgs args); ``` The return type is void. Events are based on delegates and are @@ -97,13 +97,13 @@ a pattern, and raise the correct event when a match is discovered. ```cs public class FileSearcher { - public event EventHandler OnFoundFile; + public event EventHandler FileFound; public void Search(string directory, string searchPattern) { foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) { - OnFoundFile?.Invoke(this, new FileFoundArgs(file)); + FileFound?.Invoke(this, new FileFoundArgs(file)); } } } @@ -115,7 +115,7 @@ The simplest way to add an event to your class is to declare that event as a public field, as in the above example: ```cs -public event EventHandler OnFoundFile; +public event EventHandler FileFound; ``` This looks like it's declaring a public field, which would appear to @@ -126,15 +126,15 @@ that the event objects can only be accessed in safe ways. The only operations available on a field-like event are add handler: ```cs -EventHandler handler = (sender, eventArgs) => +EventHandler onFileFound = (sender, eventArgs) => Console.WriteLine(eventArgs.FoundFile); -lister.OnFoundFile += handler; +lister.FileFound += onFIleFound; ``` and remove handler: ```cs -lister.OnFoundFile -= handler; +lister.FileFound -= onFileFound; ``` Note that there's a local variable for the handler. If you used @@ -205,7 +205,7 @@ public void List(string directory, string searchPattern) foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) { var args = new FileFoundArgs(file); - OnFoundFile?.Invoke(this, args); + FileFound?.Invoke(this, args); if (args.CancelRequested) break; } @@ -221,7 +221,7 @@ Let's update the subscriber so that it requests a cancellation once it finds the first executable: ```cs -EventHandler handler = (sender, eventArgs) => +EventHandler onFileFound = (sender, eventArgs) => { Console.WriteLine(eventArgs.FoundFile); eventArgs.CancelRequested = true; @@ -270,12 +270,12 @@ need extra code in those handlers in this project, but this shows how you would create them. ```cs -internal event EventHandler OnChangeDirectory +internal event EventHandler DirectoryChanged { - add { changeDirectory += value; } - remove { changeDirectory -= value; } + add { directoryChanged += value; } + remove { directoryChanged -= value; } } -private event EventHandler changeDirectory; +private EventHandler directoryChanged; ``` In may ways, the code you write here mirrors the code the compiler @@ -302,13 +302,13 @@ public void Search(string directory, string searchPattern, bool searchSubDirs = var totalDirs = allDirectories.Length + 1; foreach (var dir in allDirectories) { - changeDirectory?.Invoke(this, + directoryChanged?.Invoke(this, new SearchDirectoryArgs(dir, totalDirs, completedDirs++)); // Recursively search this child directory: SearchDirectory(dir, searchPattern); } // Include the Current Directory: - changeDirectory?.Invoke(this, + directoryChanged?.Invoke(this, new SearchDirectoryArgs(directory, totalDirs, completedDirs++)); SearchDirectory(directory, searchPattern); } @@ -323,7 +323,7 @@ private void SearchDirectory(string directory, string searchPattern) foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) { var args = new FileFoundArgs(file); - OnFoundFile?.Invoke(this, args); + FileFound?.Invoke(this, args); if (args.CancelRequested) break; } @@ -332,14 +332,14 @@ private void SearchDirectory(string directory, string searchPattern) At this point, you can run the application calling the overload for searching all sub-directories. There are no subscribers on the new -`OnChangeDirectory` event, but using the `?.Invoke()` idiom ensures +`ChangeDirectory` event, but using the `?.Invoke()` idiom ensures that this works correctly. Let's add a handler to write a line that shows the progress in the console window. ```cs -lister.OnChangeDirectory += (sender, eventArgs) => +lister.DirectoryChanged += (sender, eventArgs) => { Console.Write($"Entering '{eventArgs.CurrentSearchDirectory}'."); Console.WriteLine($" {eventArgs.CompletedDirs} of {eventArgs.TotalDirs} completed..."); diff --git a/docs/csharp/events-overview.md b/docs/csharp/events-overview.md index d2677121c01dc..df6601cbfa4d2 100644 --- a/docs/csharp/events-overview.md +++ b/docs/csharp/events-overview.md @@ -65,25 +65,30 @@ an extension of the syntax for delegates. To define an event you use the `event` keyword: ```cs -public event EventHandler OnProgress; +public event EventHandler Progress; ``` The type of the event (`EventHandler` in this example) must be a delegate type. There are a number of conventions that you should follow when declaring an event. Typically, the event delegate type has a void return. -Prefix event declarations with 'On'. -The remainder of the name is a verb. Use past tense (as in this example) when +Event declarations should be a verb, or a verb phrase. +Use past tense (as in this example) when the event reports something that has happened. Use a present tense verb (for -example, `OnClosing`) to report something that is about to happen. Often, using -present tense indicates that the event supports cancellation. For example, -an `OnClosing` event may include an argument that would indicate if the close -operation should continue, or not. - -When you want to raise the event, you call the event using the delegate invocation +example, `Closing`) to report something that is about to happen. Often, using +present tense indicates that your class supports some kind of customization +behavior. One of the most common scenarios is to support cancellation. For example, +a `Closing` event may include an argument that would indicate if the close +operation should continue, or not. Other scenarios may enable callers to modify +behavior by updating properties of the event arguments. You may raise an +event to indicate a proposed next action an algorithm will take. The event +handler may mandate a different action by modifying properties of the event +argument. + +When you want to raise the event, you call the event handlers using the delegate invocation syntax: ```cs -OnProgress?.Invoke(this, new FileListArgs(file)); +Progress?.Invoke(this, new FileListArgs(file)); ``` As discussed in the section on [delegates](delegates-patterns.md), the ?. @@ -93,15 +98,18 @@ when there are no subscribers to that event. You subscribe to an event by using the `+=` operator: ```cs -EventHandler handler = (sender, eventArgs) => +EventHandler onProgress = (sender, eventArgs) => Console.WriteLine(eventArgs.FoundFile); -lister.OnProgress += handler; +lister.Progress += OnProgress; ``` +The handler method typically is the prefix 'On' followed +by the event name, as shown above. + You unsubscribe using the `-=` operator: ```cs -lister.OnProgress -= handler; +lister.Progress -= onProgress; ``` It's important to note that I declared a local variable for the expression that diff --git a/docs/csharp/modern-events.md b/docs/csharp/modern-events.md index 577946c09fd3c..59b254b4508f0 100644 --- a/docs/csharp/modern-events.md +++ b/docs/csharp/modern-events.md @@ -93,7 +93,7 @@ create a safe `async void` method. The basics of the pattern you need to implement are below: ```cs -worker.OnStartWorking += async (sender, eventArgs) => +worker.StartWorking += async (sender, eventArgs) => { try { diff --git a/samples/csharp/events/Program.cs b/samples/csharp/events/Program.cs index f51de4c9e9db6..fb2057f3b4730 100644 --- a/samples/csharp/events/Program.cs +++ b/samples/csharp/events/Program.cs @@ -15,24 +15,24 @@ static void Main(string[] args) var lister = new FileSearcher(); int filesFound = 0; - EventHandler handler = (sender, eventArgs) => + EventHandler onFileFound = (sender, eventArgs) => { Console.WriteLine(eventArgs.FoundFile); filesFound++; //eventArgs.CancelRequested = true; }; - lister.OnFoundFile += handler; + lister.FileFound += onFileFound; - lister.OnChangeDirectory += (sender, eventArgs) => + lister.DirectoryChanged += (sender, eventArgs) => { Console.Write($"Entering '{eventArgs.CurrentSearchDirectory}'."); Console.WriteLine($" {eventArgs.CompletedDirs} of {eventArgs.TotalDirs} completed..."); }; - lister.Search(".", "*.exe", true); + lister.Search(".", "*.dll", true); - lister.OnFoundFile -= handler; + lister.FileFound -= onFileFound; } } @@ -62,13 +62,13 @@ internal SearchDirectoryArgs(string dir, int totalDirs, int completedDirs) } public class FileSearcher { - public event EventHandler OnFoundFile; - internal event EventHandler OnChangeDirectory + public event EventHandler FileFound; + internal event EventHandler DirectoryChanged { - add { changeDirectory += value; } - remove { changeDirectory -= value; } + add { directoryChanged += value; } + remove { directoryChanged -= value; } } - private event EventHandler changeDirectory; + private EventHandler directoryChanged; public void Search(string directory, string searchPattern, bool searchSubDirs = false) { @@ -79,13 +79,13 @@ public void Search(string directory, string searchPattern, bool searchSubDirs = var totalDirs = allDirectories.Length + 1; foreach (var dir in allDirectories) { - changeDirectory?.Invoke(this, + directoryChanged?.Invoke(this, new SearchDirectoryArgs(dir, totalDirs, completedDirs++)); // Recursively search this child directory: SearchDirectory(dir, searchPattern); } // Include the Current Directory: - changeDirectory?.Invoke(this, + directoryChanged?.Invoke(this, new SearchDirectoryArgs(directory, totalDirs, completedDirs++)); SearchDirectory(directory, searchPattern); } @@ -100,7 +100,7 @@ private void SearchDirectory(string directory, string searchPattern) foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) { var args = new FileFoundArgs(file); - OnFoundFile?.Invoke(this, args); + FileFound?.Invoke(this, args); if (args.CancelRequested) break; } diff --git a/samples/csharp/events/events.xproj b/samples/csharp/events/events.xproj index ac0db8c62412f..c9d7c8547baf8 100644 --- a/samples/csharp/events/events.xproj +++ b/samples/csharp/events/events.xproj @@ -9,9 +9,8 @@ fd45fa0a-8e95-4daa-aec9-63719b4e3fc9 events ..\artifacts\obj\$(MSBuildProjectName) - ..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ - 2.0