diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json
index 2a691a993e904..fe68094ebf025 100644
--- a/.openpublishing.redirection.json
+++ b/.openpublishing.redirection.json
@@ -1321,6 +1321,14 @@
{
"source_path":"docs/fsharp/language-reference/signatures.md",
"redirect_url":"/dotnet/fsharp/language-reference/signature-files"
+ },
+ {
+ "source_path":"docs/csharp/programming-guide/concepts/threading/thread-timers.md",
+ "redirect_url":"/dotnet/standard/threading/timers"
+ },
+ {
+ "source_path":"docs/visual-basic/programming-guide/concepts/threading/thread-timers.md",
+ "redirect_url":"/dotnet/standard/threading/timers"
}
]
}
diff --git a/docs/core/versions/selection.md b/docs/core/versions/selection.md
index c5b1434b89664..21031709da865 100644
--- a/docs/core/versions/selection.md
+++ b/docs/core/versions/selection.md
@@ -27,9 +27,9 @@ The rest of this document examines those four scenarios.
SDK commands include `dotnet new`, `dotnet build` or `dotnet run`. The `dotnet` CLI must choose an SDK version for any command. The .NET Core CLI uses the latest SDK installed on the machine by default. You'll use the .NET Core SDK v2.1.301 when it's installed, even if the project you are working with targets the .NET Core Runtime 2.0. Note that this is true for preview versions as well as released versions. You can take advantage of the latest SDK features and improvements while targeting earlier .NET Core runtime versions. You can target multiple runtime versions of .NET Core on different projects, using the same SDK tools for all projects.
-On rare occasions, you may need to use an earlier version of the SDK. You specify that version in a [*global.json* file](../tools/global-json.md). The "use latest" policy means you only use *global.json* to specify a .NET Core version earlier than the latest installed version.
+On rare occasions, you may need to use an earlier version of the SDK. You specify that version in a [*global.json* file](../tools/global-json.md). The "use latest" policy means you only use *global.json* to specify a .NET Core SDK version earlier than the latest installed version.
-*global.json* can be placed anywhere in the file hierarchy. The CLI searches upward from the project directory for the first *global.json* it finds. You control which projects a given *global.json* applies to by its place in the file system. The .NET CLI searches for a *global.json* file iteratively navigating the path upward from the current working directory. The first *global.json* file found specifies the version used. If that version is installed, that version is used. If the SDK specified in the *global.json* is not found, the .NET CLI rolls forward to the latest SDK installed. This is the same as the default behavior, when no *global.json** file is found.
+*global.json* can be placed anywhere in the file hierarchy. The CLI searches upward from the project directory for the first *global.json* it finds. You control which projects a given *global.json* applies to by its place in the file system. The .NET CLI searches for a *global.json* file iteratively navigating the path upward from the current working directory. The first *global.json* file found specifies the version used. If that version is installed, that version is used. If the SDK specified in the *global.json* is not found, the .NET CLI rolls forward to the latest SDK installed. This is the same as the default behavior, when no *global.json* file is found.
The following example shows the *global.json* syntax:
@@ -45,7 +45,7 @@ The process for selecting an SDK version is:
1. `dotnet` searches for a *global.json* file iteratively reverse-navigating the path upward from the current working directory.
1. `dotnet` uses the SDK specified in the first *global.json* found.
-1. `dotnet` binds to the latest installed SDK if no *global.json* is found.
+1. `dotnet` uses the latest installed SDK if no *global.json* is found.
You can learn more about selecting an SDK version in the [matching rules](../tools/global-json.md) section of the topic on *global.json*.
@@ -79,21 +79,21 @@ A few usage examples demonstrate the behavior:
- 2.0.4 is required. 2.0.5 is the highest patch version installed. 2.0.5 is used.
- 2.0.4 is required. No 2.0.* versions are installed. 1.1.1 is the highest runtime installed. An error message is displayed.
-- 2.04 is required. 2.0.0 is the latest version installed. An error message is displayed.
+- 2.0.4 is required. 2.0.0 is the highest version installed. An error message is displayed.
- 2.0.4 is required. No 2.0.* versions are installed. 2.2.2 is the highest 2.x runtime version installed. 2.2.2 is used.
- 2.0.4 is required. No 2.x versions are installed. 3.0.0 (not a currently available version) is installed. An error message is displayed.
Minor version roll-forward has one side-effect that may affect end users. Consider the following scenario:
- 2.0.4 is required. No 2.0.* versions are installed. 2.2.2 is installed. 2.2.2 is used.
-- 2.0.5 is later installed. 2.0.5 will be used for subsequent application launches, not 2.2.2. The latest patch is preferred over an updated minor version.
-- It's possible that 2.0.5 and 2.2.2 might behave differently, particularly for scenarios like serializing binary data.
+- 2.0.5 is later installed. 2.0.5 will be used for subsequent application launches, not 2.2.2. The latest patch of the required minor version is preferred over a higher minor version.
+- It's possible that 2.0.5 and 2.2.2 behave differently, particularly for scenarios like serializing binary data.
## Self-contained deployments include the selected runtime
You can publish an application as a [**self-contained distribution**](../deploying/index.md#self-contained-deployments-scd). This approach bundles the .NET Core runtime and libraries with your application. Self-contained deployments don't have a dependency on runtime environments. Runtime version selection occurs at publishing time, not run time.
-The publishing process selects the latest patch version of the given runtime family. For example, `dotnet publish` will select .NET Core 2.0.4 if it is the latest patch version in the .NET Core 2.0 runtime family. The target framework (including the latest installed security patches) are packaged with the application.
+The publishing process selects the latest patch version of the given runtime family. For example, `dotnet publish` will select .NET Core 2.0.4 if it is the latest patch version in the .NET Core 2.0 runtime family. The target framework (including the latest installed security patches) is packaged with the application.
It's an error if the minimum version specified for an application isn't satisfied. `dotnet publish` binds to the latest runtime patch version (within a given major.minor version family). `dotnet publish` doesn't support the roll-forward semantics of `dotnet run`. For more information about patches and self-contained deployments, see the article on [runtime patch selection](../deploying/runtime-patch-selection.md) in deploying .NET Core applications.
@@ -103,4 +103,4 @@ Self-contained deployments may require a specific patch version. You can overrid
2.0.4
```
-The `RuntimeFrameworkVersion` element overrides the default version policy. For self-contained deployments, the `RuntimeFrameworkVersion` specifies the *exact* runtime framework version. For framework dependent applications, the `RuntimeFrameworkVersion` specifies the *minimum* patch level of the framework.
+The `RuntimeFrameworkVersion` element overrides the default version policy. For self-contained deployments, the `RuntimeFrameworkVersion` specifies the *exact* runtime framework version. For framework dependent applications, the `RuntimeFrameworkVersion` specifies the *minimum* required runtime framework version.
diff --git a/docs/core/whats-new/dotnet-core-2-1.md b/docs/core/whats-new/dotnet-core-2-1.md
index e7322b096725e..87c53bbc89a10 100644
--- a/docs/core/whats-new/dotnet-core-2-1.md
+++ b/docs/core/whats-new/dotnet-core-2-1.md
@@ -212,11 +212,11 @@ The sockets implementation introduced in .NET Core 2.1 has a number of advantage
is the default implementation in .NET Core 2.1. However, you can configure your application to use the older class by calling the method:
```csharp
-AppContext.SetSwitch("System.Net.Http.useSocketsHttpHandler", false);
+AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
```
```vb
-AppContext.SetSwitch("System.Net.Http.useSocketsHttpHandler", False)
+AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", False)
```
You can also use an environment variable to opt out of using sockets implementations based on . To do this, set the `DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER` to either `false` or 0.
diff --git a/docs/csharp/language-reference/keywords/foreach-in.md b/docs/csharp/language-reference/keywords/foreach-in.md
index 9b0799d538204..93064248ac698 100644
--- a/docs/csharp/language-reference/keywords/foreach-in.md
+++ b/docs/csharp/language-reference/keywords/foreach-in.md
@@ -29,11 +29,11 @@ The following example shows usage of the `foreach` statement with an instance of
The next example uses the `foreach` statement with an instance of the type, which doesn't implement any interfaces:
-[!code-csharp[span example](~/samples/snippets/csharp/keywords/IterationKeywordsExamples.cs#2)]
+[!code-csharp-interactive[span example](~/samples/snippets/csharp/keywords/IterationKeywordsExamples.cs#2)]
Beginning with C# 7.3, if the enumerator's `Current` property returns a [reference return value](../../programming-guide/classes-and-structs/ref-returns.md) (`ref T` where `T` is the type of the collection element), you can declare the iteration variable with the `ref` or `ref readonly` modifier. The following example uses a `ref` iteration variable to set the value of each item in a stackalloc array. The `ref readonly` version iterates the collection to print all the values. The `readonly` declaration uses an implicit local variable declaration. Implicit variable declarations can be used with either `ref` or `ref readonly` declarations, as can explicitly typed variable declarations.
-[!code-csharp[ref span example](~/samples/snippets/csharp/keywords/IterationKeywordsExamples.cs#RefSpan)]
+[!code-csharp-interactive[ref span example](~/samples/snippets/csharp/keywords/IterationKeywordsExamples.cs#RefSpan)]
## C# language specification
diff --git a/docs/csharp/programming-guide/concepts/linq/linq-to-xml-overview.md b/docs/csharp/programming-guide/concepts/linq/linq-to-xml-overview.md
index e4d9d0ac974f1..80e4b295a6474 100644
--- a/docs/csharp/programming-guide/concepts/linq/linq-to-xml-overview.md
+++ b/docs/csharp/programming-guide/concepts/linq/linq-to-xml-overview.md
@@ -22,7 +22,7 @@ XML has been widely adopted as a way to format data in many contexts. For exampl
Another advantage of [!INCLUDE[sqltecxlinq](~/includes/sqltecxlinq-md.md)] is the ability to use query results as parameters to and object constructors enables a powerful approach to creating XML trees. This approach, called *functional construction*, enables developers to easily transform XML trees from one shape to another.
- For example, you might have a typical XML purchase order as described in [Sample XML File: Typical Purchase Order (LINQ to XML)](http://msdn.microsoft.com/library/0606c09f-6e43-4f8d-95c8-e8e2e08d2348). By using [!INCLUDE[sqltecxlinq](~/includes/sqltecxlinq-md.md)], you could run the following query to obtain the part number attribute value for every item element in the purchase order:
+ For example, you might have a typical XML purchase order as described in [Sample XML File: Typical Purchase Order (LINQ to XML)](sample-xml-file-typical-purchase-order-linq-to-xml-1.md). By using [!INCLUDE[sqltecxlinq](~/includes/sqltecxlinq-md.md)], you could run the following query to obtain the part number attribute value for every item element in the purchase order:
```csharp
IEnumerable partNos =
diff --git a/docs/csharp/programming-guide/concepts/threading/index.md b/docs/csharp/programming-guide/concepts/threading/index.md
index 25093904048a2..7f59944af68fe 100644
--- a/docs/csharp/programming-guide/concepts/threading/index.md
+++ b/docs/csharp/programming-guide/concepts/threading/index.md
@@ -35,7 +35,6 @@ Threading enables your C# program to perform concurrent processing so that you c
|[Parameters and Return Values for Multithreaded Procedures (C#)](../../../../csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md)|Describes how to pass and return parameters with multithreaded applications.|
|[Walkthrough: Multithreading with the BackgroundWorker Component (C#)](../../../../csharp/programming-guide/concepts/threading/walkthrough-multithreading-with-the-backgroundworker-component.md)|Shows how to create a simple multithreaded application.|
|[Thread Synchronization (C#)](../../../../csharp/programming-guide/concepts/threading/thread-synchronization.md)|Describes how to control the interactions of threads.|
-|[Thread Timers (C#)](../../../../csharp/programming-guide/concepts/threading/thread-timers.md)|Describes how to run procedures on separate threads at fixed intervals.|
|[Thread Pooling (C#)](../../../../csharp/programming-guide/concepts/threading/thread-pooling.md)|Describes how to use a pool of worker threads that are managed by the system.|
|[How to: Use a Thread Pool (C#)](../../../../csharp/programming-guide/concepts/threading/how-to-use-a-thread-pool.md)|Demonstrates synchronized use of multiple threads in the thread pool.|
|[Threading](../../../../../docs/standard/threading/index.md)|Describes how to implement threading in the .NET Framework.|
diff --git a/docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md b/docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md
index e00c557249a20..2597223ddf52f 100644
--- a/docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md
+++ b/docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md
@@ -109,7 +109,7 @@ private void BackgroundWorker1_RunWorkerCompleted(
}
```
- You can provide parameters and return values to thread-pool threads by using the optional `ByVal` state-object variable of the method. Thread-timer threads also support a state object for this purpose. For information on thread pooling and thread timers, see [Thread Pooling (C#)](../../../../csharp/programming-guide/concepts/threading/thread-pooling.md) and [Thread Timers (C#)](../../../../csharp/programming-guide/concepts/threading/thread-timers.md).
+ You can provide parameters and return values to thread-pool threads by using the optional `ByVal` state-object variable of the method. Thread-timer threads also support a state object for this purpose. For information on thread pooling and thread timers, see [Thread Pooling (C#)](../../../../csharp/programming-guide/concepts/threading/thread-pooling.md) and [Timers](../../../../standard/threading/timers.md).
## See Also
[Walkthrough: Multithreading with the BackgroundWorker Component (C#)](../../../../csharp/programming-guide/concepts/threading/walkthrough-multithreading-with-the-backgroundworker-component.md)
diff --git a/docs/csharp/programming-guide/concepts/threading/thread-timers.md b/docs/csharp/programming-guide/concepts/threading/thread-timers.md
deleted file mode 100644
index 0c43a0cac74f6..0000000000000
--- a/docs/csharp/programming-guide/concepts/threading/thread-timers.md
+++ /dev/null
@@ -1,68 +0,0 @@
----
-title: "Thread Timers (C#)"
-ms.date: 07/20/2015
-ms.assetid: 52ed71e8-4fd9-43a4-ae40-04cce7cff23f
----
-# Thread Timers (C#)
-The class is useful for periodically running a task on a separate thread. For example, you could use a thread timer to check the status and integrity of a database or to back up critical files.
-
-## Thread Timer Example
- The following example starts a task every two seconds and uses a flag to initiate the method that stops the timer. This example posts status to the output window.
-
-```csharp
-private class StateObjClass
-{
- // Used to hold parameters for calls to TimerTask.
- public int SomeValue;
- public System.Threading.Timer TimerReference;
- public bool TimerCanceled;
-}
-
-public void RunTimer()
-{
- StateObjClass StateObj = new StateObjClass();
- StateObj.TimerCanceled = false;
- StateObj.SomeValue = 1;
- System.Threading.TimerCallback TimerDelegate =
- new System.Threading.TimerCallback(TimerTask);
-
- // Create a timer that calls a procedure every 2 seconds.
- // Note: There is no Start method; the timer starts running as soon as
- // the instance is created.
- System.Threading.Timer TimerItem =
- new System.Threading.Timer(TimerDelegate, StateObj, 2000, 2000);
-
- // Save a reference for Dispose.
- StateObj.TimerReference = TimerItem;
-
- // Run for ten loops.
- while (StateObj.SomeValue < 10)
- {
- // Wait one second.
- System.Threading.Thread.Sleep(1000);
- }
-
- // Request Dispose of the timer object.
- StateObj.TimerCanceled = true;
-}
-
-private void TimerTask(object StateObj)
-{
- StateObjClass State = (StateObjClass)StateObj;
- // Use the interlocked class to increment the counter variable.
- System.Threading.Interlocked.Increment(ref State.SomeValue);
- System.Diagnostics.Debug.WriteLine("Launched new thread " + DateTime.Now.ToString());
- if (State.TimerCanceled)
- // Dispose Requested.
- {
- State.TimerReference.Dispose();
- System.Diagnostics.Debug.WriteLine("Done " + DateTime.Now.ToString());
- }
-}
-```
-
- Thread timers are particularly useful when the object is unavailable, such as when you are developing console applications.
-
-## See Also
-
- [Multithreaded Applications (C#)](../../../../csharp/programming-guide/concepts/threading/multithreaded-applications.md)
diff --git a/docs/csharp/programming-guide/concepts/threading/toc.md b/docs/csharp/programming-guide/concepts/threading/toc.md
index 1e3af3afe5020..6c05a7373bff5 100644
--- a/docs/csharp/programming-guide/concepts/threading/toc.md
+++ b/docs/csharp/programming-guide/concepts/threading/toc.md
@@ -3,6 +3,5 @@
## [Parameters and Return Values for Multithreaded Procedures](parameters-and-return-values-for-multithreaded-procedures.md)
## [Walkthrough: Multithreading with the BackgroundWorker Component](walkthrough-multithreading-with-the-backgroundworker-component.md)
## [Thread Synchronization](thread-synchronization.md)
-## [Thread Timers](thread-timers.md)
## [Thread Pooling](thread-pooling.md)
### [How to: Use a Thread Pool](how-to-use-a-thread-pool.md)
diff --git a/docs/csharp/programming-guide/events/codesnippet/CSharp/how-to-implement-interface-events_1.cs b/docs/csharp/programming-guide/events/codesnippet/CSharp/how-to-implement-interface-events_1.cs
index d840dff02cc2b..f56cd26dbb513 100644
--- a/docs/csharp/programming-guide/events/codesnippet/CSharp/how-to-implement-interface-events_1.cs
+++ b/docs/csharp/programming-guide/events/codesnippet/CSharp/how-to-implement-interface-events_1.cs
@@ -1,3 +1,4 @@
+#region everything
namespace WrapTwoInterfaceEvents
{
using System;
@@ -29,6 +30,7 @@ public class Shape : IDrawingObject, IShape
// Explicit interface implementation required.
// Associate IDrawingObject's event with
// PreDrawEvent
+ #region IDrawingObjectOnDraw
event EventHandler IDrawingObject.OnDraw
{
add
@@ -46,6 +48,8 @@ event EventHandler IDrawingObject.OnDraw
}
}
}
+ #endregion
+
// Explicit interface implementation required.
// Associate IShape's event with
// PostDrawEvent
@@ -133,3 +137,4 @@ Sub1 receives the IDrawingObject event.
Drawing a shape.
Sub2 receives the IShape event.
*/
+#endregion
\ No newline at end of file
diff --git a/docs/csharp/programming-guide/events/how-to-implement-custom-event-accessors.md b/docs/csharp/programming-guide/events/how-to-implement-custom-event-accessors.md
index 492f26e11b446..17c30185555d1 100644
--- a/docs/csharp/programming-guide/events/how-to-implement-custom-event-accessors.md
+++ b/docs/csharp/programming-guide/events/how-to-implement-custom-event-accessors.md
@@ -15,25 +15,7 @@ An event is a special kind of multicast delegate that can only be invoked from w
## Example
The following example shows how to implement custom add and remove event accessors. Although you can substitute any code inside the accessors, we recommend that you lock the event before you add or remove a new event handler method.
-```csharp
-event EventHandler IDrawingObject.OnDraw
-{
- add
- {
- lock (PreDrawEvent)
- {
- PreDrawEvent += value;
- }
- }
- remove
- {
- lock (PreDrawEvent)
- {
- PreDrawEvent -= value;
- }
- }
-}
-```
+[!code-csharp[IDrawingObject.OnDraw](codesnippet/CSharp/how-to-implement-interface-events_1.cs#IDrawingObjectOnDraw)]
## See Also
[Events](../../../csharp/programming-guide/events/index.md)
diff --git a/docs/csharp/programming-guide/events/how-to-implement-interface-events.md b/docs/csharp/programming-guide/events/how-to-implement-interface-events.md
index be3b95fdc2b9c..bd851433a9ccb 100644
--- a/docs/csharp/programming-guide/events/how-to-implement-interface-events.md
+++ b/docs/csharp/programming-guide/events/how-to-implement-interface-events.md
@@ -9,47 +9,47 @@ ms.assetid: 63527447-9535-4880-8e95-35e2075827df
# How to: Implement Interface Events (C# Programming Guide)
An [interface](../../../csharp/language-reference/keywords/interface.md) can declare an [event](../../../csharp/language-reference/keywords/event.md). The following example shows how to implement interface events in a class. Basically the rules are the same as when you implement any interface method or property.
-### To implement interface events in a class
+## To implement interface events in a class
-- Declare the event in your class and then invoke it in the appropriate areas.
+Declare the event in your class and then invoke it in the appropriate areas.
- ```csharp
- namespace ImplementInterfaceEvents
+```csharp
+namespace ImplementInterfaceEvents
+{
+ public interface IDrawingObject
{
- public interface IDrawingObject
- {
- event EventHandler ShapeChanged;
- }
- public class MyEventArgs : EventArgs
+ event EventHandler ShapeChanged;
+ }
+ public class MyEventArgs : EventArgs
+ {
+ // class members
+ }
+ public class Shape : IDrawingObject
+ {
+ public event EventHandler ShapeChanged;
+ void ChangeShape()
{
- // class members
+ // Do something here before the event…
+
+ OnShapeChanged(new MyEventArgs(/*arguments*/));
+
+ // or do something here after the event.
}
- public class Shape : IDrawingObject
+ protected virtual void OnShapeChanged(MyEventArgs e)
{
- public event EventHandler ShapeChanged;
- void ChangeShape()
- {
- // Do something here before the event…
-
- OnShapeChanged(new MyEventArgs(/*arguments*/));
-
- // or do something here after the event.
- }
- protected virtual void OnShapeChanged(MyEventArgs e)
- {
- ShapeChanged?.Invoke(this, e);
- }
+ ShapeChanged?.Invoke(this, e);
}
-
}
- ```
+
+}
+```
## Example
The following example shows how to handle the less-common situation in which your class inherits from two or more interfaces and each interface has an event with the same name. In this situation, you must provide an explicit interface implementation for at least one of the events. When you write an explicit interface implementation for an event, you must also write the `add` and `remove` event accessors. Normally these are provided by the compiler, but in this case the compiler cannot provide them.
By providing your own accessors, you can specify whether the two events are represented by the same event in your class, or by different events. For example, if the events should be raised at different times according to the interface specifications, you can associate each event with a separate implementation in your class. In the following example, subscribers determine which `OnDraw` event they will receive by casting the shape reference to either an `IShape` or an `IDrawingObject`.
- [!code-csharp[csProgGuideEvents#10](../../../csharp/programming-guide/events/codesnippet/CSharp/how-to-implement-interface-events_1.cs)]
+ [!code-csharp[WrapTwoInterfaceEvents](../../../csharp/programming-guide/events/codesnippet/CSharp/how-to-implement-interface-events_1.cs#everything)]
## See Also
[C# Programming Guide](../../../csharp/programming-guide/index.md)
diff --git a/docs/csharp/tutorials/inheritance.md b/docs/csharp/tutorials/inheritance.md
index 279098154113d..edd713799b69e 100644
--- a/docs/csharp/tutorials/inheritance.md
+++ b/docs/csharp/tutorials/inheritance.md
@@ -3,7 +3,7 @@ title: Inheritance in C#
description: Learn to use inheritance in C# libraries and applications.
author: rpetrusha
ms.author: ronpet
-ms.date: 08/16/2017
+ms.date: 07/05/2018
ms.assetid: aeb68c74-0ea0-406f-9fbe-2ce02d47ef31
---
# Inheritance in C# and .NET
@@ -27,7 +27,6 @@ To create and run the examples in this tutorial, you use the [dotnet](../../core
1. Enter the [dotnet run](../../core/tools/dotnet-run.md) command to compile and execute the example.
-
## Background: What is inheritance?
*Inheritance* is one of the fundamental attributes of object-oriented programming. It allows you to define a child class that reuses (inherits), extends, or modifies the behavior of a parent class. The class whose members are inherited is called the *base class*. The class that inherits the members of the base class is called the *derived class*.
@@ -52,7 +51,7 @@ While all other members of a base class are inherited by derived classes, whethe
- [Internal](../language-reference/keywords/internal.md) members are visible only in derived classes that are located in the same assembly as the base class. They are not visible in derived classes located in a different assembly from the base class.
-- [Public](../language-reference/keywords/public.md) members are visible in derived classes and are part of the derived class' public interface. Public inherited members can be called just as if they were defined in the derived class. In the following example, class `A` defines a method named `Method1`, and class `B` inherits from class `A`. The example then calls `Method1` as if it were an instance method on `B`.
+- [Public](../language-reference/keywords/public.md) members are visible in derived classes and are part of the derived class' public interface. Public inherited members can be called just as if they are defined in the derived class. In the following example, class `A` defines a method named `Method1`, and class `B` inherits from class `A`. The example then calls `Method1` as if it were an instance method on `B`.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/basics.cs#1)]
@@ -93,7 +92,7 @@ public class B : A // Generates CS0534.
}
```
-Inheritance applies only to classes and interfaces. Other type categories (structs, delegates, and enums) do not support inheritance. Because of this, attempting to compile code like the following produces compiler error CS0527: "Type 'ValueType' in interface list is not an interface." The error message indicates that, although you can define the interfaces that a struct implements, inheritance is not supported.
+Inheritance applies only to classes and interfaces. Other type categories (structs, delegates, and enums) do not support inheritance. Because of these rules, attempting to compile code like the following example produces compiler error CS0527: "Type 'ValueType' in interface list is not an interface." The error message indicates that, although you can define the interfaces that a struct implements, inheritance is not supported.
```csharp
using System;
@@ -105,13 +104,13 @@ public struct ValueStructure : ValueType // Generates CS0527.
## Implicit inheritance
-Besides any types that they may inherit from through single inheritance, all types in the .NET type system implicitly inherit from or a type derived from it. This ensures that common functionality is available to any type.
+Besides any types that they may inherit from through single inheritance, all types in the .NET type system implicitly inherit from or a type derived from it. The common functionality of is available to any type.
To see what implicit inheritance means, let's define a new class, `SimpleClass`, that is simply an empty class definition:
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/simpleclass.cs#1)]
-We can then use reflection (which lets us inspect a type's metadata to get information about that type) to get a list of the members that belong to the `SimpleClass` type. Although we haven't defined any members in our `SimpleClass` class, output from the example indicates that it actually has nine members. One of these is a parameterless (or default) constructor that is automatically supplied for the `SimpleClass` type by the C# compiler. The remaining eight are members of , the type from which all classes and interfaces in the .NET type system ultimately implicitly inherit.
+You can then use reflection (which lets you inspect a type's metadata to get information about that type) to get a list of the members that belong to the `SimpleClass` type. Although you haven't defined any members in your `SimpleClass` class, output from the example indicates that it actually has nine members. One of these members is a parameterless (or default) constructor that is automatically supplied for the `SimpleClass` type by the C# compiler. The remaining eight are members of , the type from which all classes and interfaces in the .NET type system ultimately implicitly inherit.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/simpleclass.cs#2)]
@@ -129,7 +128,7 @@ Implicit inheritance from the class makes these methods ava
- The protected method, which creates a shallow clone of the current object.
-Because of implicit inheritance, we can call any inherited member from a `SimpleClass` object just as if it was actually a member defined in the `SimpleClass` class. For instance, the following example calls the `SimpleClass.ToString` method, which `SimpleClass` inherits from .
+Because of implicit inheritance, you can call any inherited member from a `SimpleClass` object just as if it was actually a member defined in the `SimpleClass` class. For instance, the following example calls the `SimpleClass.ToString` method, which `SimpleClass` inherits from .
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/simpleclass2.cs#1)]
@@ -149,11 +148,11 @@ Ordinarily, inheritance is used to express an "is a" relationship between a base
> [!NOTE]
> A class or struct can implement one more interfaces. While interface implementation is often presented as a workaround for single inheritance or as a way of using inheritance with structs, it is intended to express a different relationship (a "can do" relationship) between an interface and its implementing type than inheritance. An interface defines a subset of functionality (such as the ability to test for equality, to compare or sort objects, or to support culture-sensitive parsing and formatting) that the interface makes available to its implementing types.
-Note that "is a" also expresses the relationship between a type and a specific instantiation of that type. In the following example, `Automobile` is a class that has three unique read-only properties: `Make`, the manufacturer of the automobile; `Model`, the kind of automobile; and `Year`, its year of manufacture. Our `Automobile` class also has a constructor whose arguments are assigned to the property values, and it overrides the method to produce a string that uniquely identifies the `Automobile` instance rather than the `Automobile` class.
+Note that "is a" also expresses the relationship between a type and a specific instantiation of that type. In the following example, `Automobile` is a class that has three unique read-only properties: `Make`, the manufacturer of the automobile; `Model`, the kind of automobile; and `Year`, its year of manufacture. Your `Automobile` class also has a constructor whose arguments are assigned to the property values, and it overrides the method to produce a string that uniquely identifies the `Automobile` instance rather than the `Automobile` class.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/is-a.cs#1)]
-In this case, we should not rely on inheritance to represent specific car makes and models. For example, we do not need to define a `Packard` type to represent automobiles manufactured by the Packard Motor Car Company. Instead, we can represent them by creating an `Automobile` object with the appropriate values passed to its class constructor, as the following example does.
+In this case, you shouldn't rely on inheritance to represent specific car makes and models. For example, you don't need to define a `Packard` type to represent automobiles manufactured by the Packard Motor Car Company. Instead, you can represent them by creating an `Automobile` object with the appropriate values passed to its class constructor, as the following example does.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/is-a.cs#2)]
@@ -161,35 +160,37 @@ An is-a relationship based on inheritance is best applied to a base class and to
## Designing the base class and derived classes
-Let's look at the process of designing a base class and its derived classes. In this section, we'll define a base class, `Publication`, which represents a publication of any kind, such as a book, a magazine, a newspaper, a journal, an article, etc. We'll also define a `Book` class that derives from `Publication`. We could easily extend the example to define other derived classes, such as `Magazine`, `Journal`, `Newspaper`, and `Article`.
+Let's look at the process of designing a base class and its derived classes. In this section, you'll define a base class, `Publication`, which represents a publication of any kind, such as a book, a magazine, a newspaper, a journal, an article, etc. You'll also define a `Book` class that derives from `Publication`. You could easily extend the example to define other derived classes, such as `Magazine`, `Journal`, `Newspaper`, and `Article`.
### The base Publication class
-In designing our `Publication` class, we need to make several design decisions:
+In designing your `Publication` class, you need to make several design decisions:
-- What members to include in our base `Publication` class, and whether the `Publication` members provide method implementations, or whether `Publication` is an abstract base class that serves as a template for its derived classes.
+- What members to include in your base `Publication` class, and whether the `Publication` members provide method implementations or whether `Publication` is an abstract base class that serves as a template for its derived classes.
In this case, the `Publication` class will provide method implementations. The [Designing abstract base classes and their derived classes](#abstract) section contains an example that uses an abstract base class to define the methods that derived classes must override. Derived classes are free to provide any implementation that is suitable for the derived type.
- The ability to reuse code (that is, multiple derived classes share the declaration and implementation of base class methods and do not need to override them) is an advantage of non-abstract base classes. Therefore, we should add members to `Publication` if their code is likely to be shared by some or most specialized `Publication` types. If we fail to do this efficiently, we'll end up having to provide largely identical member implementations in derived classes rather a single implementation in the base class. The need to maintain duplicated code in multiple locations is a potential source of bugs.
+ The ability to reuse code (that is, multiple derived classes share the declaration and implementation of base class methods and do not need to override them) is an advantage of non-abstract base classes. Therefore, you should add members to `Publication` if their code is likely to be shared by some or most specialized `Publication` types. If you fail to provide base class implementations efficiently, you'll end up having to provide largely identical member implementations in derived classes rather a single implementation in the base class. The need to maintain duplicated code in multiple locations is a potential source of bugs.
+
+ Both to maximize code reuse and to create a logical and intuitive inheritance hierarchy, you want to be sure that you include in the `Publication` class only the data and functionality that is common to all or to most publications. Derived classes then implement members that are unique to the particular kinds of publication that they represent.
- Both to maximize code reuse and to create a logical and intuitive inheritance hierarchy, we want to be sure that we include in the `Publication` class only the data and functionality that is common to all or to most publications. Derived classes then implement members that are unique to the particular kinds of publication that they represent.
+- How far to extend your class hierarchy. Do you want to develop a hierarchy of three or more classes, rather than simply a base class and one or more derived classes? For example, `Publication` could be a base class of `Periodical`, which in turn is a base class of `Magazine`, `Journal` and `Newspaper`.
-- How far to extend our class hierarchy. Do we want to develop a hierarchy of three or more classes, rather than simply a base class and one or more derived classes? For example, `Publication` could be a base class of `Periodical`, which in turn is a base class of `Magazine`, `Journal` and `Newspaper`.
+ For your example, you'll use the small hierarchy of a `Publication` class and a single derived class, `Book`. You could easily extend the example to create a number of additional classes that derive from `Publication`, such as `Magazine` and `Article`.
- For our example, we'll use the simple hierarchy of a `Publication` class and a single derived classes, `Book`. We could easily extend the example to create a number of additional classes that derive from `Publication`, such as `Magazine` and `Article`.
+- Whether it makes sense to instantiate the base class. If it does not, you should apply the [abstract](../language-reference/keywords/abstract.md) keyword to the class. Otherwise, your `Publication` class can be instantiated by calling its class constructor. If an attempt is made to instantiate a class marked with the `abstract` keyword by a direct call to its class constructor, the C# compiler generates error CS0144, "Cannot create an instance of the abstract class or interface." If an attempt is made to instantiate the class by using reflection, the reflection method throws a .
-- Whether it makes sense to instantiate the base class. If it does not, we should apply the [abstract](../language-reference/keywords/abstract.md) keyword to the class. If an attempt is made to instantiate a class marked with the `abstract` keyword by a direct call to its class constructor, the C# compiler generates error CS0144, "Cannot create an instance of the abstract class or interface." If an attempt is made to instantiate the class by using reflection, the reflection method throws a . Otherwise, our `Publication` class can be instantiated by calling its class constructor.
+ By default, a base class can be instantiated by calling its class constructor. You do not have to explicitly define a class constructor. If one is not present in the base class' source code, the C# compiler automatically provides a default (parameterless) constructor.
- By default, a base class can be instantiated by calling its class constructor. Note that we do not have to explicitly define a class constructor. If one is not present in the base class' source code, the C# compiler automatically provides a default (parameterless) constructor.
+ For your example, you'll mark the `Publication` class as [abstract](../language-reference/keywords/abstract.md) so that it cannot be instantiated. An `abstract` class without any `abstract` methods indicates that this class represents an abstract concept that is shared among several concrete classes (like a `Book`, `Journal`).
- For our example, we'll mark the `Publication` class as [abstract](../language-reference/keywords/abstract.md) so that it cannot be instantiated.
+- Whether derived classes must inherit the base class implementation of particular members, whether they have the option to override the base class implementation, or whether they must provide an implementation. You use the [abstract](../language-reference/keywords/abstract.md) keyword to force derived classes to provide an implementation. You use the [virtual](../language-reference/keywords/virtual.md) keyword to allow derived classes to override a base class method. By default, methods defined in the base class are *not* overridable.
-- Whether derived classes must inherit the base class implementation of a particular members, or whether they have the option to override the base class implementation. We have to use the [virtual](../language-reference/keywords/virtual.md) keyword to allow derived classes to override a base class method. By default, methods defined in the base class are *not* overridable.
+ The `Publication` class does not have any `abstract` methods, but the class itself is `abstract`.
-- Whether a derived class represents the final class in the inheritance hierarchy and cannot itself be used as a base class for additional derived classes. By default, any class can serve as a base class. We can apply the [sealed](../language-reference/keywords/sealed.md) keyword to indicate that a class cannot serve as a base class for any additional classes. Attempting to derive from a sealed class generated compiler error CS0509, "cannot derive from sealed type ".
+- Whether a derived class represents the final class in the inheritance hierarchy and cannot itself be used as a base class for additional derived classes. By default, any class can serve as a base class. You can apply the [sealed](../language-reference/keywords/sealed.md) keyword to indicate that a class cannot serve as a base class for any additional classes. Attempting to derive from a sealed class generated compiler error CS0509, "cannot derive from sealed type ".
- For our example, we'll mark our derived class as `sealed`.
+ For your example, you'll mark your derived class as `sealed`.
The following example shows the source code for the `Publication` class, as well as a `PublicationType` enumeration that is returned by the `Publication.PublicationType` property. In addition to the members that it inherits from , the `Publication` class defines the following unique members and member overrides:
@@ -197,7 +198,7 @@ The following example shows the source code for the `Publication` class, as well
- A constructor
- Because the `Publication` class is `abstract`, it cannot be instantiated directly from code like the following:
+ Because the `Publication` class is `abstract`, it cannot be instantiated directly from code like the following example:
```csharp
var publication = new Publication("Tiddlywinks for Experts", "Fun and Games",
@@ -228,7 +229,7 @@ The following example shows the source code for the `Publication` class, as well
If a type does not override the method, it returns the fully qualified name of the type, which is of little use in differentiating one instance from another. The `Publication` class overrides to return the value of the `Title` property.
-The following figure illustrates the relationship between our base `Publication` class and its implicitly inherited class.
+The following figure illustrates the relationship between your base `Publication` class and its implicitly inherited class.

@@ -244,7 +245,7 @@ In addition to the members that it inherits from `Publication`, the `Book` class
The two `Book` constructors share three common parameters. Two, *title* and *publisher*, correspond to parameters of the `Publication` constructor. The third is *author*, which is stored to a private `authorName` field. One constructor includes an *isbn* parameter, which is stored in the `ISBN` auto-property.
- The first constructor uses the [this](../language-reference/keywords/this.md) keyword to call the other constructor. This is a common pattern in defining constructors. Constructors with fewer parameters provide default values when calling the constructor with the greatest number of parameters.
+ The first constructor uses the [this](../language-reference/keywords/this.md) keyword to call the other constructor. Constructor chaining is a common pattern in defining constructors. Constructors with fewer parameters provide default values when calling the constructor with the greatest number of parameters.
The second constructor uses the [base](../language-reference/keywords/base.md) keyword to pass the title and publisher name to the base class constructor. If you don't make an explicit call to a base class constructor in your source code, the C# compiler automatically supplies a call to the base class' default or parameterless constructor.
@@ -254,38 +255,38 @@ In addition to the members that it inherits from `Publication`, the `Book` class
- Two read-only price-related properties, `Price` and `Currency`. Their values are provided as arguments in a `SetPrice` method call. The price is stored in a private field, `bookPrice`. The `Currency` property is the three-digit ISO currency symbol (for example, USD for the U.S. dollar) and is stored in the private `ISOCurrencySymbol` field. ISO currency symbols can be retrieved from the property.
-- A `SetPrice` method, which sets the values of the `bookPrice` and `ISOCurrencySymbol` fields. These are the values returned by the `Price` and `Currency` properties.
+- A `SetPrice` method, which sets the values of the `bookPrice` and `ISOCurrencySymbol` fields. Those values are returned by the `Price` and `Currency` properties.
- Overrides to the `ToString` method (inherited from `Publication`) and the and methods (inherited from ).
- Unless it is overridden, the method tests for reference equality. That is, two object variables are considered to be equal if they refer to the same object. In the case of the `Book` class, on the other hand, two `Book` objects should be equal if they have the same ISBN.
+ Unless it is overridden, the method tests for reference equality. That is, two object variables are considered to be equal if they refer to the same object. In the `Book` class, on the other hand, two `Book` objects should be equal if they have the same ISBN.
- When you override the method, you must also override the method, which returns a value that the runtime uses to store items in hashed collections for efficient retrieval. The hash code should return a value that's consistent with the test for equality. Since we've overridden to return `true` if the ISBN properties of two `Book` objects are equal, we return the hash code computed by calling the method of the string returned by the `ISBN` property.
+ When you override the method, you must also override the method, which returns a value that the runtime uses to store items in hashed collections for efficient retrieval. The hash code should return a value that's consistent with the test for equality. Since you've overridden to return `true` if the ISBN properties of two `Book` objects are equal, you return the hash code computed by calling the method of the string returned by the `ISBN` property.
The following figure illustrates the relationship between the `Book` class and `Publication`, its base class.

-We can now instantiate a `Book` object, invoke both its unique and inherited members, and pass it as an argument to a method that expects a parameter of type `Publication` or of type `Book`, as the following example shows.
+You can now instantiate a `Book` object, invoke both its unique and inherited members, and pass it as an argument to a method that expects a parameter of type `Publication` or of type `Book`, as the following example shows.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/use-publication.cs#1)]
## Designing abstract base classes and their derived classes
-In the previous example, we defined a base class that provided an implementation for a number of methods to allow derived classes to share code. In many cases, however, the base class is not expected to provide an implementation. Instead, the base class is an *abstract class*; it serves as a template that defines the members that each derived class must implement. Typically in the case of an abstract base class, the implementation of each derived type is unique to that type.
+In the previous example, you defined a base class that provided an implementation for a number of methods to allow derived classes to share code. In many cases, however, the base class is not expected to provide an implementation. Instead, the base class is an *abstract class* that declares *abstract methods*; it serves as a template that defines the members that each derived class must implement. Typically in an abstract base class, the implementation of each derived type is unique to that type. You marked the class with the abstract keyword because it made no sense to instantiate a `Publication` object, although the class did provide implementations of functionality common to publications.
-For example, each closed two-dimensional geometric shape includes two properties: area, the inner extent of the shape; and perimeter, or the distance along the edges of the shape. The way in which these properties are calculated, however, depends completely on the specific shape. The formula for calculating the perimeter (or circumference) of a circle, for example, is very different from that of a triangle.
+For example, each closed two-dimensional geometric shape includes two properties: area, the inner extent of the shape; and perimeter, or the distance along the edges of the shape. The way in which these properties are calculated, however, depends completely on the specific shape. The formula for calculating the perimeter (or circumference) of a circle, for example, is different from that of a triangle. The `Shape` class is an `abstract` class with `abstract` methods. That indicates derived classes share the same functionality, but those derived classes implement that functionality differently.
-The following example defines an abstract base class named `Shape` that defines two properties: `Area` and `Perimeter`. Note that, in addition to marking the class with the [abstract](../language-reference/keywords/abstract.md) keyword, each instance member is also marked with the [abstract](../language-reference/keywords/abstract.md) keyword. In this case, `Shape` also overrides the method to return the name of the type, rather than its fully qualified name. And it defines two static members, `GetArea` and `GetPerimeter`, that allow callers to easily retrieve the area and perimeter of an instance of any derived class. When we pass an instance of a derived class to either of these methods, the runtime calls the method override of the derived class.
+The following example defines an abstract base class named `Shape` that defines two properties: `Area` and `Perimeter`. In addition to marking the class with the [abstract](../language-reference/keywords/abstract.md) keyword, each instance member is also marked with the [abstract](../language-reference/keywords/abstract.md) keyword. In this case, `Shape` also overrides the method to return the name of the type, rather than its fully qualified name. And it defines two static members, `GetArea` and `GetPerimeter`, that allow callers to easily retrieve the area and perimeter of an instance of any derived class. When you pass an instance of a derived class to either of these methods, the runtime calls the method override of the derived class.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/shape.cs#1)]
-We can then derive some classes from `Shape` that represent specific shapes. The following example defines three classes, `Triangle`, `Rectangle`, and `Circle`. Each uses a formula unique for that particular shape to compute the area and perimeter. Some of the derived classes also define properties, such as `Rectangle.Diagonal` and `Circle.Diameter`, that are unique to the shape that they represent.
+You can then derive some classes from `Shape` that represent specific shapes. The following example defines three classes, `Triangle`, `Rectangle`, and `Circle`. Each uses a formula unique for that particular shape to compute the area and perimeter. Some of the derived classes also define properties, such as `Rectangle.Diagonal` and `Circle.Diameter`, that are unique to the shape that they represent.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/shape.cs#2)]
-The following example uses objects derived from `Shape`. It instantiates an array of objects derived from `Shape` and calls the static methods of the `Shape` class, which wraps return `Shape` property values. Note that the runtime retrieves values from the overridden properties of the derived types. The example also casts each `Shape` object in the array to its derived type and, if the cast succeeds, retrieves properties of that particular subclass of `Shape`.
+The following example uses objects derived from `Shape`. It instantiates an array of objects derived from `Shape` and calls the static methods of the `Shape` class, which wraps return `Shape` property values. The runtime retrieves values from the overridden properties of the derived types. The example also casts each `Shape` object in the array to its derived type and, if the cast succeeds, retrieves properties of that particular subclass of `Shape`.
[!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/shape.cs#3)]
diff --git a/docs/framework/configure-apps/file-schema/network/mailsettings-element-network-settings.md b/docs/framework/configure-apps/file-schema/network/mailsettings-element-network-settings.md
index a4fa80bc0327a..ad5f1b928a384 100644
--- a/docs/framework/configure-apps/file-schema/network/mailsettings-element-network-settings.md
+++ b/docs/framework/configure-apps/file-schema/network/mailsettings-element-network-settings.md
@@ -52,7 +52,7 @@ Configures mail sending options.
-
+
-
+
-
+
-
+
diff --git a/docs/framework/data/adonet/ef/language-reference/entity-sql-reference.md b/docs/framework/data/adonet/ef/language-reference/entity-sql-reference.md
index 7c47b71316576..94976960bb890 100644
--- a/docs/framework/data/adonet/ef/language-reference/entity-sql-reference.md
+++ b/docs/framework/data/adonet/ef/language-reference/entity-sql-reference.md
@@ -44,12 +44,12 @@ Equality and inequality are defined for any object type that has identity, such
|[= (Equals)](equals-entity-sql.md)|Compares the equality of two expressions.|
|[> (Greater Than)](greater-than-entity-sql.md)|Compares two expressions to determine whether the left expression has a value greater than the right expression.|
|[>= (Greater Than or Equal To)](greater-than-or-equal-to-entity-sql.md)|Compares two expressions to determine whether the left expression has a value greater than or equal to the right expression.|
-|[IS [NOT] NULL](isnull-entity-sql.md)|Determines if a query expression is null.|
+|[IS \[NOT\] NULL](isnull-entity-sql.md)|Determines if a query expression is null.|
|[< (Less Than)](less-than-entity-sql.md)|Compares two expressions to determine whether the left expression has a value less than the right expression.|
|[<= (Less Than or Equal To)](less-than-or-equal-to-entity-sql.md)|Compares two expressions to determine whether the left expression has a value less than or equal to the right expression.|
-|[[NOT] BETWEEN](between-entity-sql.md)|Determines whether an expression results in a value in a specified range.|
+|[\[NOT\] BETWEEN](between-entity-sql.md)|Determines whether an expression results in a value in a specified range.|
|[!= (Not Equal To)](not-equal-to-entity-sql.md)|Compares two expressions to determine whether the left expression isn't equal to the right expression.|
-|[[NOT] LIKE](like-entity-sql.md)|Determines whether a specific character string matches a specified pattern.|
+|[\[NOT\] LIKE](like-entity-sql.md)|Determines whether a specific character string matches a specified pattern.|
## Logical and case expression operators
@@ -100,9 +100,9 @@ Entity SQL provides various powerful set operations. This includes set operators
|--------------|---------|
|[ANYELEMENT](anyelement-entity-sql.md)|Extracts an element from a multivalued collection.|
|[EXCEPT](except-entity-sql.md)|Returns a collection of any distinct values from the query expression to the left of the EXCEPT operand that aren't also returned from the query expression to the right of the EXCEPT operand.|
-|[[NOT] EXISTS](exists-entity-sql.md)|Determines if a collection is empty.|
+|[\[NOT\] EXISTS](exists-entity-sql.md)|Determines if a collection is empty.|
|[FLATTEN](flatten-entity-sql.md)|Converts a collection of collections into a flattened collection.|
-|[[NOT] IN](in-entity-sql.md)|Determines whether a value matches any value in a collection.|
+|[\[NOT\] IN](in-entity-sql.md)|Determines whether a value matches any value in a collection.|
|[INTERSECT](intersect-entity-sql.md)|Returns a collection of any distinct values that are returned by both the query expressions on the left and right sides of the INTERSECT operand.|
|[OVERLAPS](overlaps-entity-sql.md)|Determines whether two collections have common elements.|
|[SET](set-entity-sql.md)|Used to convert a collection of objects into a set by yielding a new collection with all duplicate elements removed.|
@@ -116,7 +116,7 @@ Entity SQL provides operations that allow the type of an expression (value) to b
|--------------|---------|
|[CAST](cast-entity-sql.md)|Converts an expression of one data type to another.|
|[COLLECTION](collection-entity-sql.md)|Used in a [FUNCTION](function-entity-sql.md) operation to declare a collection of entity types or complex types.|
-|[IS [NOT] OF](isof-entity-sql.md)|Determines whether the type of an expression is of the specified type or one of its subtypes.|
+|[IS \[NOT\] OF](isof-entity-sql.md)|Determines whether the type of an expression is of the specified type or one of its subtypes.|
|[OFTYPE](oftype-entity-sql.md)|Returns a collection of objects from a query expression that is of a specific type.|
|[Named Type Constructor](named-type-constructor-entity-sql.md)|Used to create instances of entity types or complex types.|
|[MULTISET](multiset-entity-sql.md)|Creates an instance of a multiset from a list of values.|
diff --git a/docs/framework/data/adonet/sql-server-connection-pooling.md b/docs/framework/data/adonet/sql-server-connection-pooling.md
index 6e551a7833ead..9de286b57872b 100644
--- a/docs/framework/data/adonet/sql-server-connection-pooling.md
+++ b/docs/framework/data/adonet/sql-server-connection-pooling.md
@@ -66,8 +66,7 @@ using (SqlConnection connection = new SqlConnection(
> [!NOTE]
> Do not call `Close` or `Dispose` on a `Connection`, a `DataReader`, or any other managed object in the `Finalize` method of your class. In a finalizer, only release unmanaged resources that your class owns directly. If your class does not own any unmanaged resources, do not include a `Finalize` method in your class definition. For more information, see [Garbage Collection](../../../../docs/standard/garbage-collection/index.md).
-> [!NOTE]
-> Login and logout events will not be raised on the server when a connection is fetched from or returned to the connection pool. This is because the connection is not actually closed when it is returned to the connection pool. For more information, see [Audit Login Event Class](http://msdn2.microsoft.com/library/ms190260.aspx) and [Audit Logout Event Class](http://msdn2.microsoft.com/library/ms175827.aspx) in SQL Server Books Online.
+For more info about the events associated with opening and closing connections, see [Audit Login Event Class](/sql/relational-databases/event-classes/audit-login-event-class) and [Audit Logout Event Class](/sql/relational-databases/event-classes/audit-logout-event-class) in the SQL Server documentation.
## Removing Connections
The connection pooler removes a connection from the pool after it has been idle for approximately 4-8 minutes, or if the pooler detects that the connection with the server has been severed. Note that a severed connection can be detected only after attempting to communicate with the server. If a connection is found that is no longer connected to the server, it is marked as invalid. Invalid connections are removed from the connection pool only when they are closed or reclaimed.
diff --git a/docs/framework/interop/how-to-generate-interop-assemblies-from-type-libraries.md b/docs/framework/interop/how-to-generate-interop-assemblies-from-type-libraries.md
index 35abea6d41e57..1f53afe8168f3 100644
--- a/docs/framework/interop/how-to-generate-interop-assemblies-from-type-libraries.md
+++ b/docs/framework/interop/how-to-generate-interop-assemblies-from-type-libraries.md
@@ -26,13 +26,13 @@ The [Type Library Importer (Tlbimp.exe)](../../../docs/framework/tools/tlbimp-ex
The following command produces the Loanlib.dll assembly in the `Loanlib` namespace.
```
-tlbimp Loanlib.dll
+tlbimp Loanlib.tlb
```
The following command produces an interop assembly with an altered name (LOANLib.dll).
```
-tlbimp LoanLib.dll /out: LOANLib.dll
+tlbimp LoanLib.tlb /out: LOANLib.dll
```
## See Also
diff --git a/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md b/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md
index fb6f696f71e40..33233d690d054 100644
--- a/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md
+++ b/docs/framework/net-native/migrating-your-windows-store-app-to-net-native.md
@@ -6,7 +6,7 @@ author: "rpetrusha"
ms.author: "ronpet"
---
# Migrating Your Windows Store App to .NET Native
-[!INCLUDE[net_native](../../../includes/net-native-md.md)] provides static compilation of apps in the Windows Store or on the developer’s computer. This differs from the dynamic compilation performed for Windows Store apps by the just-in-time (JIT) compiler or the [Native Image Generator (Ngen.exe)](../../../docs/framework/tools/ngen-exe-native-image-generator.md) on the device. Despite the differences, [!INCLUDE[net_native](../../../includes/net-native-md.md)] tries to maintain compatibility with the [.NET for Windows Store apps](http://msdn.microsoft.com/library/windows/apps/br230302.aspx). For the most part, things that work on the .NET for Windows Store apps also work with [!INCLUDE[net_native](../../../includes/net-native-md.md)]. However, in some cases, you may encounter behavioral changes. This document discusses these differences between the standard .NET for Windows Store apps and [!INCLUDE[net_native](../../../includes/net-native-md.md)] in the following areas:
+.NET Native provides static compilation of apps in the Windows Store or on the developer’s computer. This differs from the dynamic compilation performed for Windows Store apps by the just-in-time (JIT) compiler or the [Native Image Generator (Ngen.exe)](../../../docs/framework/tools/ngen-exe-native-image-generator.md) on the device. Despite the differences, .NET Native tries to maintain compatibility with the [.NET for Windows Store apps](http://msdn.microsoft.com/library/windows/apps/br230302.aspx). For the most part, things that work on the .NET for Windows Store apps also work with .NET Native. However, in some cases, you may encounter behavioral changes. This document discusses these differences between the standard .NET for Windows Store apps and .NET Native in the following areas:
- [General runtime differences](#Runtime)
@@ -21,36 +21,36 @@ ms.author: "ronpet"
## General runtime differences
-- Exceptions, such as , that are thrown by the JIT compiler when an app runs on the common language runtime (CLR) generally result in compile-time errors when processed by [!INCLUDE[net_native](../../../includes/net-native-md.md)].
+- Exceptions, such as , that are thrown by the JIT compiler when an app runs on the common language runtime (CLR) generally result in compile-time errors when processed by .NET Native.
-- Don't call the method from an app's UI thread. This can result in a deadlock on [!INCLUDE[net_native](../../../includes/net-native-md.md)].
+- Don't call the method from an app's UI thread. This can result in a deadlock on .NET Native.
-- Don't rely on static class constructor invocation ordering. In [!INCLUDE[net_native](../../../includes/net-native-md.md)], the invocation order is different from the order on the standard runtime. (Even with the standard runtime, you shouldn't rely on the order of execution of static class constructors.)
+- Don't rely on static class constructor invocation ordering. In .NET Native, the invocation order is different from the order on the standard runtime. (Even with the standard runtime, you shouldn't rely on the order of execution of static class constructors.)
- Infinite looping without making a call (for example, `while(true);`) on any thread may bring the app to a halt. Similarly, large or infinite waits may bring the app to a halt.
-- Certain generic initialization cycles don't throw exceptions in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. For example, the following code throws a exception on the standard CLR. In [!INCLUDE[net_native](../../../includes/net-native-md.md)], it doesn't.
+- Certain generic initialization cycles don't throw exceptions in .NET Native. For example, the following code throws a exception on the standard CLR. In .NET Native, it doesn't.
[!code-csharp[ProjectN#8](../../../samples/snippets/csharp/VS_Snippets_CLR/projectn/cs/compat1.cs#8)]
-- In some cases, [!INCLUDE[net_native](../../../includes/net-native-md.md)] provides different implementations of .NET Framework class libraries. An object returned from a method will always implement the members of the returned type. However, since its backing implementation is different, you may not be able to cast it to the same set of types as you could on other .NET Framework platforms. For example, in some cases, you may not be able to cast the interface object returned by methods such as or to `T[]`.
+- In some cases, .NET Native provides different implementations of .NET Framework class libraries. An object returned from a method will always implement the members of the returned type. However, since its backing implementation is different, you may not be able to cast it to the same set of types as you could on other .NET Framework platforms. For example, in some cases, you may not be able to cast the interface object returned by methods such as or to `T[]`.
-- The WinInet cache isn't enabled by default on .NET for Windows Store apps, but it is on [!INCLUDE[net_native](../../../includes/net-native-md.md)]. This improves performance but has working set implications. No developer action is necessary.
+- The WinInet cache isn't enabled by default on .NET for Windows Store apps, but it is on .NET Native. This improves performance but has working set implications. No developer action is necessary.
## Dynamic programming differences
- [!INCLUDE[net_native](../../../includes/net-native-md.md)] statically links in code from the .NET Framework to make the code app-local for maximum performance. However, binary sizes have to remain small, so the entire .NET Framework can't be brought in. The [!INCLUDE[net_native](../../../includes/net-native-md.md)] compiler resolves this limitation by using a dependency reducer that removes references to unused code. However, [!INCLUDE[net_native](../../../includes/net-native-md.md)] might not maintain or generate some type information and code when that information can't be inferred statically at compile time, but instead is retrieved dynamically at runtime.
+ .NET Native statically links in code from the .NET Framework to make the code app-local for maximum performance. However, binary sizes have to remain small, so the entire .NET Framework can't be brought in. The .NET Native compiler resolves this limitation by using a dependency reducer that removes references to unused code. However, .NET Native might not maintain or generate some type information and code when that information can't be inferred statically at compile time, but instead is retrieved dynamically at runtime.
- [!INCLUDE[net_native](../../../includes/net-native-md.md)] does enable reflection and dynamic programming. However, not all types can be marked for reflection, because this would make the generated code size too large (especially because reflecting on public APIs in the .NET Framework is supported). The [!INCLUDE[net_native](../../../includes/net-native-md.md)] compiler makes smart choices about which types should support reflection, and it keeps the metadata and generates code only for those types.
+ .NET Native does enable reflection and dynamic programming. However, not all types can be marked for reflection, because this would make the generated code size too large (especially because reflecting on public APIs in the .NET Framework is supported). The .NET Native compiler makes smart choices about which types should support reflection, and it keeps the metadata and generates code only for those types.
- For example, data binding requires an app to be able to map property names to functions. In .NET for Windows Store apps, the common language runtime automatically uses reflection to provide this capability for managed types and publicly available native types. In [!INCLUDE[net_native](../../../includes/net-native-md.md)], the compiler automatically includes metadata for types to which you bind data.
+ For example, data binding requires an app to be able to map property names to functions. In .NET for Windows Store apps, the common language runtime automatically uses reflection to provide this capability for managed types and publicly available native types. In .NET Native, the compiler automatically includes metadata for types to which you bind data.
- The [!INCLUDE[net_native](../../../includes/net-native-md.md)] compiler can also handle commonly used generic types such as and , which work without requiring any hints or directives. The [dynamic](~/docs/csharp/language-reference/keywords/dynamic.md) keyword is also supported within certain limits.
+ The .NET Native compiler can also handle commonly used generic types such as and , which work without requiring any hints or directives. The [dynamic](~/docs/csharp/language-reference/keywords/dynamic.md) keyword is also supported within certain limits.
> [!NOTE]
-> You should test all dynamic code paths thoroughly when porting your app to [!INCLUDE[net_native](../../../includes/net-native-md.md)].
+> You should test all dynamic code paths thoroughly when porting your app to .NET Native.
- The default configuration for [!INCLUDE[net_native](../../../includes/net-native-md.md)] is sufficient for most developers, but some developers might want to fine- tune their configurations by using a runtime directives (.rd.xml) file. In addition, in some cases, the [!INCLUDE[net_native](../../../includes/net-native-md.md)] compiler is unable to determine which metadata must be available for reflection and relies on hints, particularly in the following cases:
+ The default configuration for .NET Native is sufficient for most developers, but some developers might want to fine- tune their configurations by using a runtime directives (.rd.xml) file. In addition, in some cases, the .NET Native compiler is unable to determine which metadata must be available for reflection and relies on hints, particularly in the following cases:
- Some constructs like and can't be determined statically.
@@ -59,13 +59,13 @@ ms.author: "ronpet"
> [!NOTE]
> Runtime directives are defined in a runtime directives (.rd.xml) file. For general information about using this file, see [Getting Started](../../../docs/framework/net-native/getting-started-with-net-native.md). For information about the runtime directives, see [Runtime Directives (rd.xml) Configuration File Reference](../../../docs/framework/net-native/runtime-directives-rd-xml-configuration-file-reference.md).
- [!INCLUDE[net_native](../../../includes/net-native-md.md)] also includes profiling tools that help the developer determine which types outside the default set should support reflection.
+ .NET Native also includes profiling tools that help the developer determine which types outside the default set should support reflection.
## Other reflection-related differences
- There are a number of other individual reflection-related differences in behavior between the .NET for Windows Store apps and [!INCLUDE[net_native](../../../includes/net-native-md.md)].
+ There are a number of other individual reflection-related differences in behavior between the .NET for Windows Store apps and .NET Native.
- In [!INCLUDE[net_native](../../../includes/net-native-md.md)]:
+ In .NET Native:
- Private reflection over types and members in the .NET Framework class library is not supported. You can, however, reflect over your own private types and members, as well as types and members in third-party libraries.
@@ -81,7 +81,7 @@ ms.author: "ronpet"
- You can't use reflection to get or set a pointer field.
-- When the argument count is wrong and the type of one of the arguments is incorrect, [!INCLUDE[net_native](../../../includes/net-native-md.md)] throws an instead of a .
+- When the argument count is wrong and the type of one of the arguments is incorrect, .NET Native throws an instead of a .
- Binary serialization of exceptions is generally not supported. As a result, non-serializable objects can be added to the dictionary.
@@ -101,11 +101,11 @@ ms.author: "ronpet"
### General development differences
**Value types**
-- If you override the and methods for a value type, don't call the base class implementations. In .NET for Windows Store apps, these methods rely on reflection. At compile time, [!INCLUDE[net_native](../../../includes/net-native-md.md)] generates an implementation that doesn't rely on runtime reflection. This means that if you don't override these two methods, they will work as expected, because [!INCLUDE[net_native](../../../includes/net-native-md.md)] generates the implementation at compile time. However, overriding these methods but calling the base class implementation results in an exception.
+- If you override the and methods for a value type, don't call the base class implementations. In .NET for Windows Store apps, these methods rely on reflection. At compile time, .NET Native generates an implementation that doesn't rely on runtime reflection. This means that if you don't override these two methods, they will work as expected, because .NET Native generates the implementation at compile time. However, overriding these methods but calling the base class implementation results in an exception.
- Value types larger than one megabyte aren't supported.
-- Value types can't have a default constructor in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. (C# and Visual Basic prohibit default constructors on value types. However, these can be created in IL.)
+- Value types can't have a default constructor in .NET Native. (C# and Visual Basic prohibit default constructors on value types. However, these can be created in IL.)
**Arrays**
@@ -141,39 +141,35 @@ ms.author: "ronpet"
`Delegate.BeginInvoke` and `Delegate.EndInvoke` aren't supported.
- **Async**
-
- Threading logic in overloads of Task IAsync isn't supported.
-
**Miscellaneous APIs**
- The property throws a exception if a attribute isn't applied to the type. The GUID is used primarily for COM support.
-- The method correctly parses strings that contain short dates in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. However, it doesn't maintain compatibility with the changes in date and time parsing described in the Microsoft Knowledge Base articles [KB2803771](http://support.microsoft.com/kb/2803771) and [KB2803755](http://support.microsoft.com/kb/2803755).
+- The method correctly parses strings that contain short dates in .NET Native. However, it doesn't maintain compatibility with the changes in date and time parsing described in the Microsoft Knowledge Base articles [KB2803771](http://support.microsoft.com/kb/2803771) and [KB2803755](http://support.microsoft.com/kb/2803755).
-- `("E")` is correctly rounded in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. In some versions of the CLR, the result string is truncated instead of rounded.
+- `("E")` is correctly rounded in .NET Native. In some versions of the CLR, the result string is truncated instead of rounded.
### HttpClient differences
- In [!INCLUDE[net_native](../../../includes/net-native-md.md)], the class internally uses WinINet (through the [HttpBaseProtocolFilter](http://msdn.microsoft.com/library/windows/apps/windows.web.http.filters.httpbaseprotocolfilter.aspx) class) instead of the and classes used in the standard .NET for Windows Store apps. WinINet doesn't support all the configuration options that the class supports. As a result:
+ In .NET Native, the class internally uses WinINet (through the [HttpBaseProtocolFilter](http://msdn.microsoft.com/library/windows/apps/windows.web.http.filters.httpbaseprotocolfilter.aspx) class) instead of the and classes used in the standard .NET for Windows Store apps. WinINet doesn't support all the configuration options that the class supports. As a result:
-- Some of the capability properties on return `false` on [!INCLUDE[net_native](../../../includes/net-native-md.md)], whereas they return `true` in the standard .NET for Windows Store apps.
+- Some of the capability properties on return `false` on .NET Native, whereas they return `true` in the standard .NET for Windows Store apps.
-- Some of the configuration property `get` accessors always return a fixed value on [!INCLUDE[net_native](../../../includes/net-native-md.md)] that is different than the default configurable value in .NET for Windows Store apps.
+- Some of the configuration property `get` accessors always return a fixed value on .NET Native that is different than the default configurable value in .NET for Windows Store apps.
Some additional behavior differences are covered in the following subsections.
**Proxy**
- The [HttpBaseProtocolFilter](http://msdn.microsoft.com/library/windows/apps/windows.web.http.filters.httpbaseprotocolfilter.aspx) class doesn’t support configuring or overriding the proxy on a per-request basis. This means that all requests on [!INCLUDE[net_native](../../../includes/net-native-md.md)] use the system-configured proxy server or no proxy server, depending on the value of the property. In .NET for Windows Store apps, the proxy server is defined by the property. On [!INCLUDE[net_native](../../../includes/net-native-md.md)], setting the to a value other than `null` throws a exception. The property returns `false` on [!INCLUDE[net_native](../../../includes/net-native-md.md)], whereas it returns `true` in the standard .NET Framework for Windows Store apps.
+ The [HttpBaseProtocolFilter](http://msdn.microsoft.com/library/windows/apps/windows.web.http.filters.httpbaseprotocolfilter.aspx) class doesn’t support configuring or overriding the proxy on a per-request basis. This means that all requests on .NET Native use the system-configured proxy server or no proxy server, depending on the value of the property. In .NET for Windows Store apps, the proxy server is defined by the property. On .NET Native, setting the to a value other than `null` throws a exception. The property returns `false` on .NET Native, whereas it returns `true` in the standard .NET Framework for Windows Store apps.
**Automatic redirection**
- The [HttpBaseProtocolFilter](http://msdn.microsoft.com/library/windows/apps/windows.web.http.filters.httpbaseprotocolfilter.aspx) class doesn't allow the maximum number of automatic redirections to be configured. The value of the property is 50 by default in the standard .NET for Windows Store apps and can be modified. On [!INCLUDE[net_native](../../../includes/net-native-md.md)], the value of this property is 10, and trying to modify it throws a exception. The property returns `false` on [!INCLUDE[net_native](../../../includes/net-native-md.md)], whereas it returns `true` in .NET for Windows Store apps.
+ The [HttpBaseProtocolFilter](http://msdn.microsoft.com/library/windows/apps/windows.web.http.filters.httpbaseprotocolfilter.aspx) class doesn't allow the maximum number of automatic redirections to be configured. The value of the property is 50 by default in the standard .NET for Windows Store apps and can be modified. On .NET Native, the value of this property is 10, and trying to modify it throws a exception. The property returns `false` on .NET Native, whereas it returns `true` in .NET for Windows Store apps.
**Automatic decompression**
- .NET for Windows Store apps allows you to set the property to , , both and , or . [!INCLUDE[net_native](../../../includes/net-native-md.md)] only supports together with , or . Trying to set the property to either or alone silently sets it to both and .
+ .NET for Windows Store apps allows you to set the property to , , both and , or . .NET Native only supports together with , or . Trying to set the property to either or alone silently sets it to both and .
**Cookies**
@@ -181,11 +177,11 @@ ms.author: "ronpet"
**Credentials**
- In .NET for Windows Store apps, the and properties work independently. Additionally, the property accepts any object that implements the interface. In [!INCLUDE[net_native](../../../includes/net-native-md.md)], setting the property to `true` causes the property to become `null`. In addition, the property can be set only to `null`, , or an object of type . Assigning any other object, the most popular of which is , to the property throws a .
+ In .NET for Windows Store apps, the and properties work independently. Additionally, the property accepts any object that implements the interface. In .NET Native, setting the property to `true` causes the property to become `null`. In addition, the property can be set only to `null`, , or an object of type . Assigning any other object, the most popular of which is , to the property throws a .
**Other unsupported or unconfigurable features**
- In [!INCLUDE[net_native](../../../includes/net-native-md.md)]:
+ In .NET Native:
- The value of the property is always . In .NET for Windows Store apps, the default is .
@@ -199,7 +195,7 @@ ms.author: "ronpet"
### Interop differences
**Deprecated APIs**
- A number of infrequently used APIs for interoperability with managed code have been deprecated. When used with [!INCLUDE[net_native](../../../includes/net-native-md.md)], these APIs may throw a or exception, or result in a compiler error. In .NET for Windows Store apps, these APIs are marked as obsolete, although calling them generates a compiler warning rather than a compiler error.
+ A number of infrequently used APIs for interoperability with managed code have been deprecated. When used with .NET Native, these APIs may throw a or exception, or result in a compiler error. In .NET for Windows Store apps, these APIs are marked as obsolete, although calling them generates a compiler warning rather than a compiler error.
Deprecated APIs for `VARIANT` marshaling:
@@ -232,7 +228,7 @@ ms.author: "ronpet"
||
||
- Deprecated APIs in the interface, which isn't supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)]:
+ Deprecated APIs in the interface, which isn't supported in .NET Native:
|Type|Member|
|----------|------------|
@@ -270,7 +266,7 @@ ms.author: "ronpet"
**Platform invoke and COM interop compatibility**
- Most platform invoke and COM interop scenarios are still supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. In particular, all interoperability with Windows Runtime (WinRT) APIs and all marshaling required for the Windows Runtime is supported. This includes marshaling support for:
+ Most platform invoke and COM interop scenarios are still supported in .NET Native. In particular, all interoperability with Windows Runtime (WinRT) APIs and all marshaling required for the Windows Runtime is supported. This includes marshaling support for:
- Arrays (including )
@@ -318,7 +314,7 @@ ms.author: "ronpet"
- [IUnknown](http://msdn.microsoft.com/library/windows/desktop/ms680509.aspx)
- However, [!INCLUDE[net_native](../../../includes/net-native-md.md)] doesn't support the following:
+ However, .NET Native doesn't support the following:
- Using classic COM events
@@ -330,11 +326,11 @@ ms.author: "ronpet"
### Other differences from .NET APIs for Windows Store apps
- This section lists the remaining APIs that aren't supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. The largest set of the unsupported APIs are Windows Communication Foundation (WCF) APIs.
+ This section lists the remaining APIs that aren't supported in .NET Native. The largest set of the unsupported APIs are Windows Communication Foundation (WCF) APIs.
**DataAnnotations (System.ComponentModel.DataAnnotations)**
- The types in the and namespaces aren't supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. These include the following types that are present in the .NET for Windows Store apps for Windows 8:
+ The types in the and namespaces aren't supported in .NET Native. These include the following types that are present in the .NET for Windows Store apps for Windows 8:
||
|-|
@@ -366,7 +362,7 @@ ms.author: "ronpet"
**Visual Basic**
- Visual Basic isn't currently supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. The following types in the and namespaces aren't available in [!INCLUDE[net_native](../../../includes/net-native-md.md)]:
+ Visual Basic isn't currently supported in .NET Native. The following types in the and namespaces aren't available in .NET Native:
||
|-|
@@ -390,15 +386,15 @@ ms.author: "ronpet"
**Reflection Context (System.Reflection.Context namespace)**
- The class isn't supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)].
+ The class isn't supported in .NET Native.
**RTC (System.Net.Http.Rtc)**
- The class isn't supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)].
+ The class isn't supported in .NET Native.
**Windows Communication Foundation (WCF) (System.ServiceModel.\*)**
- The types in the [System.ServiceModel.* namespaces](http://msdn.microsoft.com/library/gg145010.aspx) aren't supported in [!INCLUDE[net_native](../../../includes/net-native-md.md)]. These includes the following types:
+ The types in the [System.ServiceModel.* namespaces](http://msdn.microsoft.com/library/gg145010.aspx) aren't supported in .NET Native. These includes the following types:
||
|-|
@@ -584,7 +580,7 @@ ms.author: "ronpet"
### Differences in serializers
The following differences concern serialization and deserialization with the , , and classes:
-- In [!INCLUDE[net_native](../../../includes/net-native-md.md)], and fail to serialize or deserialize a derived class that has a base class member whose type isn't a root serialization type. For example, in the following code, trying to serialize or deserialize `Y` results in an error:
+- In .NET Native, and fail to serialize or deserialize a derived class that has a base class member whose type isn't a root serialization type. For example, in the following code, trying to serialize or deserialize `Y` results in an error:
[!code-csharp[ProjectN#10](../../../samples/snippets/csharp/VS_Snippets_CLR/projectn/cs/compat3.cs#10)]
@@ -646,7 +642,7 @@ ms.author: "ronpet"
## Visual Studio differences
**Exceptions and debugging**
- When you're running apps compiled by using [!INCLUDE[net_native](../../../includes/net-native-md.md)] in the debugger, first-chance exceptions are enabled for the following exception types:
+ When you're running apps compiled by using .NET Native in the debugger, first-chance exceptions are enabled for the following exception types:
-
@@ -666,7 +662,7 @@ ms.author: "ronpet"
**Unit Test Library projects**
- Enabling [!INCLUDE[net_native](../../../includes/net-native-md.md)] on a Unit Test Library for a Windows Store apps project isn't supported and causes the project to fail to build.
+ Enabling .NET Native on a Unit Test Library for a Windows Store apps project isn't supported and causes the project to fail to build.
## See Also
[Getting Started](../../../docs/framework/net-native/getting-started-with-net-native.md)
diff --git a/docs/fsharp/get-started/get-started-command-line.md b/docs/fsharp/get-started/get-started-command-line.md
index e0382c0450b1a..9f92639fefcad 100644
--- a/docs/fsharp/get-started/get-started-command-line.md
+++ b/docs/fsharp/get-started/get-started-command-line.md
@@ -9,21 +9,21 @@ This article covers how you can get started with F# on any operating system (Win
## Prerequisites
-To begin, you must install the [.NET Core SDK 1.0 or later](https://www.microsoft.com/net/download/). There is no need to uninstall a previous version of the .NET Core SDK, as it supports side-by-side installations.
+To begin, you must install the latest [.NET Core SDK](https://www.microsoft.com/net/download/).
-This article assumes that you know how to use a command line and have a preferred text editor. If you don't already use it, [Visual Studio Code](https://code.visualstudio.com) is a great option as a text editor for F#. To get awesome features like IntelliSense, better syntax highlighting, and more, you can download the [Ionide Extension](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-fsharp).
+This article assumes that you know how to use a command line and have a preferred text editor. If you don't already use it, [Visual Studio Code](get-started-vscode.md) is a great option as a text editor for F#.
## Build a simple multi-project solution
Open a command prompt/terminal and use the [dotnet new](../../core/tools/dotnet-new.md) command to create new solution file called `FSNetCore`:
-```
+```console
dotnet new sln -o FSNetCore
```
The following directory structure is produced after running the previous command:
-```
+```console
FSNetCore
├── FSNetCore.sln
```
@@ -34,13 +34,13 @@ Change directories to *FSNetCore*.
Use the `dotnet new` command, create a class library project in the **src** folder named Library.
-```
+```console
dotnet new lib -lang F# -o src/Library
```
The following directory structure is produced after running the previous command:
-```
+```console
└── FSNetCore
├── FSNetCore.sln
└── src
@@ -62,29 +62,29 @@ let getJsonNetJson value =
Add the Newtonsoft.Json NuGet package to the Library project.
-```
+```console
dotnet add src/Library/Library.fsproj package Newtonsoft.Json
```
Add the `Library` project to the `FSNetCore` solution using the [dotnet sln add](../../core/tools/dotnet-sln.md) command:
-```
+```console
dotnet sln add src/Library/Library.fsproj
```
-Restore the NuGet dependencies using the `dotnet restore` command ([see note](#dotnet-restore-note)) and run `dotnet build` to build the project.
+Run `dotnet build` to build the project. Unresolved dependencies will be restored when building.
### Write a console application that consumes the class library
Use the `dotnet new` command, create a console application in the **src** folder named App.
-```
+```console
dotnet new console -lang F# -o src/App
```
The following directory structure is produced after running the previous command:
-```
+```console
└── FSNetCore
├── FSNetCore.sln
└── src
@@ -115,13 +115,13 @@ let main argv =
Add a reference to the `Library` project using [dotnet add reference](../../core/tools/dotnet-add-reference.md).
-```
+```console
dotnet add src/App/App.fsproj reference src/Library/Library.fsproj
```
Add the `App` project to the `FSNetCore` solution using the `dotnet sln add` command:
-```
+```console
dotnet sln add src/App/App.fsproj
```
@@ -129,19 +129,20 @@ Restore the NuGet dependencies, `dotnet restore` ([see note](#dotnet-restore-not
Change directory to the `src/App` console project and run the project passing `Hello World` as arguments:
-```
+```console
cd src/App
dotnet run Hello World
```
You should see the following results:
-```
+```console
Nice command-line arguments! Here's what JSON.NET has to say about them:
I used to be Hello but now I'm ""Hello"" thanks to JSON.NET!
I used to be World but now I'm ""World"" thanks to JSON.NET!
```
-
-[!INCLUDE[DotNet Restore Note](~/includes/dotnet-restore-note.md)]
\ No newline at end of file
+## Next steps
+
+Next, check out the [Tour of F#](../tour.md) to learn more about different F# features.
\ No newline at end of file
diff --git a/docs/fsharp/get-started/get-started-visual-studio.md b/docs/fsharp/get-started/get-started-visual-studio.md
index c7c37da5407e2..c0e601844431e 100644
--- a/docs/fsharp/get-started/get-started-visual-studio.md
+++ b/docs/fsharp/get-started/get-started-visual-studio.md
@@ -1,29 +1,13 @@
---
title: Get started with F# in Visual Studio
description: Learn how to use F# with Visual Studio.
-ms.date: 02/13/2017
+ms.date: 07/03/2018
---
# Get started with F# in Visual Studio
-F# and the Visual F# tooling are supported in the Visual Studio IDE. To begin, you should [download Visual Studio](https://aka.ms/vsdownload?utm_source=mscom&utm_campaign=msdocs), if you haven't already. This article uses the Visual Studio 2017 Community Edition, but you can use F# with the version of your choice.
+F# and the Visual F# tooling are supported in the Visual Studio IDE.
-## Installing F# #
-
-If you're downloading Visual Studio for the first time, it will first install the Visual Studio installer. Install any version of Visual Studio 2017 from the installer. If you already have it installed, click **Modify**.
-
-You'll next see a list of Workloads. You can install F# through any of the following workloads:
-
-|Workload|Action|
-|--------|------|
-| .NET Core cross-platform development | No action - F# is installed by default |
-| ASP.NET and web development | No action - F# is installed by default |
-| Azure development | No action - F# is installed by default |
-| Mobile development with .NET | No action - F# is installed by default |
-| Data science and analytical applications | No action - F# is installed by default |
-| .NET desktop development | Select **F# desktop language support** from the right-hand side |
-| Data storage and processing | Select **F# desktop language support** from the right-hand side |
-
-Next, click **Modify** in the lower right-hand side. This will install everything you have selected. You can then open Visual Studio 2017 with F# language support by clicking **Launch**.
+To begin, ensure that you have [Visual Studio installed with F#](install-fsharp.md#install-f-with-visual-studio).
## Creating a console application
@@ -72,8 +56,7 @@ Congratulations! You've created your first F# project in Visual Studio, written
If you haven't already, check out the [Tour of F#](../tour.md), which covers some of the core features of the F# language. It will give you an overview of some of the capabilities of F#, and provide ample code samples that you can copy into Visual Studio and run. There are also some great external resources you can use, showcased in the [F# Guide](../index.md).
## See also
- [Visual F#](index.md)
- [Tour of F#](../tour.md)
- [F# language reference](../language-reference/index.md)
- [Type inference](../language-reference/type-inference.md)
- [Symbol and operator reference](../language-reference/symbol-and-operator-reference/index.md)
+ [Tour of F#](../tour.md)
+ [F# language reference](../language-reference/index.md)
+ [Type inference](../language-reference/type-inference.md)
+ [Symbol and operator reference](../language-reference/symbol-and-operator-reference/index.md)
diff --git a/docs/fsharp/get-started/get-started-vscode.md b/docs/fsharp/get-started/get-started-vscode.md
index 92fd4ec67e57b..c9eaa7045bf9d 100644
--- a/docs/fsharp/get-started/get-started-vscode.md
+++ b/docs/fsharp/get-started/get-started-vscode.md
@@ -5,48 +5,9 @@ ms.date: 05/28/2018
---
# Get Started with F# in Visual Studio Code
-You can write F# in [Visual Studio Code](https://code.visualstudio.com) with the [Ionide plugin](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-fsharp), to get a great cross-platform, lightweight Integrated Development Environment (IDE) experience with IntelliSense and basic code refactorings. Visit [Ionide.io](http://ionide.io) to learn more about the plugin suite.
+You can write F# in [Visual Studio Code](https://code.visualstudio.com) with the [Ionide plugin](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-fsharp) to get a great cross-platform, lightweight Integrated Development Environment (IDE) experience with IntelliSense and basic code refactorings. Visit [Ionide.io](http://ionide.io) to learn more about the plugin.
-## Prerequisites
-
-You must have [git installed](https://git-scm.com/download) and available on your PATH to make use of project templates in Ionide. You can verify that it is installed correctly by typing `git --version` at a command prompt and pressing **Enter**.
-
-### [macOS](#tab/macos)
-
-Ionide uses [Mono](http://www.mono-project.com). The easiest way to install Mono on macOS is via Homebrew. Simply type the following into your terminal:
-
-```
-brew install mono
-```
-
-You must also install the [.NET Core SDK](https://www.microsoft.com/net/download).
-
-### [Linux](#tab/linux)
-
-On Linux, Ionide also uses [Mono](https://www.mono-project.com). If you're on Debian or Ubuntu, you can use the following:
-
-```
-sudo apt-get update
-sudo apt-get install mono-complete fsharp
-```
-
-You must also install the [.NET Core SDK](https://www.microsoft.com/net/download).
-
-### [Windows](#tab/windows)
-
-If you're on Windows, you must [install Visual Studio with F# support](get-started-visual-studio.md#installing-f). This installs all the necessary components to write, compile, and execute F# code.
-
-You must also install the [.NET Core SDK](https://www.microsoft.com/net/download/).
-
----
-
-## Installing Visual Studio Code and the Ionide plugin
-
-You can install Visual Studio Code from the [code.visualstudio.com](https://code.visualstudio.com) website.
-
-Next, click the Extensions icon and search for "Ionide":
-
-The only plugin required for F# support in Visual Studio Code is [Ionide-fsharp](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-fsharp). However, you can also install [Ionide-FAKE](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-FAKE) to get [FAKE](https://fsharp.github.io/FAKE/) support and [Ionide-Paket](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-Paket) to get [Paket](https://fsprojects.github.io/Paket/) support. FAKE and Paket are additional F# community tools for building projects and managing dependencies, respectively.
+To begin, ensure that you have [F# and the Ionide plugin correctly installed](install-fsharp.md#install-f-with-visual-studio-code).
## Creating your first project with Ionide
diff --git a/docs/fsharp/get-started/get-started-with-visual-studio-for-mac.md b/docs/fsharp/get-started/get-started-with-visual-studio-for-mac.md
index e7ab6faaa0ac4..51a6349eec107 100644
--- a/docs/fsharp/get-started/get-started-with-visual-studio-for-mac.md
+++ b/docs/fsharp/get-started/get-started-with-visual-studio-for-mac.md
@@ -1,17 +1,11 @@
---
title: Get started with F# in Visual Studio for Mac
description: Learn how to use F# with Visual Studio for Mac.
-ms.date: 02/13/2017
+ms.date: 07/03/2018
---
# Get started with F# in Visual Studio for Mac
-F# and the Visual F# tooling are supported in the Visual Studio for Mac IDE. To begin, you should [download Visual Studio for Mac](https://aka.ms/vsdownload?utm_source=mscom&utm_campaign=msdocs), if you haven't already. This article uses the Visual Studio Community 2017 for Mac, but you can use F# with the version of your choice.
-
-## Installing F# #
-
-After downloading Visual Studio for Mac, it will prompt you to choose what you want to install. For the purposes of this article we will be leaving the defaults. In contrast to Visual Studio for Windows, you do not need to specifically install F# support. Press "Install" to proceed.
-
-After the install completes, choose "Start Visual Studio". You can also launch it through Finder on macOS.
+F# and the Visual F# tooling are supported in the Visual Studio for Mac IDE. Ensure that you have [Visual Studio for Mac installed](install-fsharp.md#install-f-with-visual-studio-for-mac).
## Creating a console application
diff --git a/docs/fsharp/get-started/install-fsharp.md b/docs/fsharp/get-started/install-fsharp.md
new file mode 100644
index 0000000000000..7237fc0830772
--- /dev/null
+++ b/docs/fsharp/get-started/install-fsharp.md
@@ -0,0 +1,62 @@
+---
+title: Install F#
+description: Learn how to install F# based on your environment.
+ms.date: 07/03/2018
+---
+
+# Install F# #
+
+You can install F# in multiple ways, depending on your environment.
+
+## Install F# with Visual Studio
+
+If you're downloading [Visual Studio](https://visualstudio.microsoft.com/) for the first time, it will first install the Visual Studio installer. Install the appropriate SKU of Visual Studio from the installer. If you already have it installed, click **Modify**.
+
+You'll next see a list of Workloads. Select **ASP.NET and web development**, which will install F# support, .NET Core support, and F# support for ASP.NET Core projects.
+
+Next, click **Modify** in the lower right-hand side. This will install everything you have selected. You can then open Visual Studio 2017 with F# language support by clicking **Launch**.
+
+## Install F# with Visual Studio for Mac
+
+F# is installed by default in [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/), no matter what configuration you choose.
+
+After the install completes, choose "Start Visual Studio". You can also launch it through Finder on macOS.
+
+## Install F# with Visual Studio Code
+
+You must have [git installed](https://git-scm.com/download) and available on your PATH to make use of project templates in Ionide. You can verify that it is installed correctly by typing `git --version` at a command prompt and pressing **Enter**.
+
+### [macOS](#tab/macos)
+
+Ionide uses [Mono](http://www.mono-project.com). The easiest way to install Mono on macOS is via Homebrew. Simply type the following into your terminal:
+
+```console
+brew install mono
+```
+
+You must also install the [.NET Core SDK](https://www.microsoft.com/net/download).
+
+### [Linux](#tab/linux)
+
+On Linux, Ionide also uses [Mono](https://www.mono-project.com). If you're on Debian or Ubuntu, you can use the following:
+
+```console
+sudo apt-get update
+sudo apt-get install mono-complete fsharp
+```
+
+You must also install the [.NET Core SDK](https://www.microsoft.com/net/download).
+
+### [Windows](#tab/windows)
+
+If you're on Windows, you must [install Visual Studio with F# support](#install-f-with-visual-studio). This installs all the necessary components to write, compile, and execute F# code.
+
+You must also install the [.NET Core SDK](https://www.microsoft.com/net/download/).
+
+---
+
+You will then need [Visual Studio Code](https://code.visualstudio.com) installed.
+
+Next, click the Extensions icon and search for "Ionide":
+
+The only plugin required for F# support in Visual Studio Code is [Ionide-fsharp](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-fsharp). However, you can also install [Ionide-FAKE](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-FAKE) to get [FAKE](https://fsharp.github.io/FAKE/) support and [Ionide-Paket](https://marketplace.visualstudio.com/items?itemName=Ionide.Ionide-Paket) to get [Paket](https://fsprojects.github.io/Paket/) support. FAKE and Paket are additional F# community tools for building projects and managing dependencies, respectively.
\ No newline at end of file
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-custom-http-call-retries-exponential-backoff.md b/docs/standard/microservices-architecture/implement-resilient-applications/explore-custom-http-call-retries-exponential-backoff.md
similarity index 71%
rename from docs/standard/microservices-architecture/implement-resilient-applications/implement-custom-http-call-retries-exponential-backoff.md
rename to docs/standard/microservices-architecture/implement-resilient-applications/explore-custom-http-call-retries-exponential-backoff.md
index ee80cebcfe786..dd23b3051a7fb 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-custom-http-call-retries-exponential-backoff.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/explore-custom-http-call-retries-exponential-backoff.md
@@ -1,17 +1,17 @@
---
-title: Implementing custom HTTP call retries with exponential backoff
-description: .NET Microservices Architecture for Containerized .NET Applications | Implementing custom HTTP call retries with exponential backoff
+title: Explore custom HTTP call retries with exponential backoff
+description: Learn how you could implement, from scratch, HTTP call retries with exponential backoff to handle possible HTTP failure scenarios.
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 05/26/2017
+ms.date: 06/08/2018
---
-# Implementing custom HTTP call retries with exponential backoff
+# Explore custom HTTP call retries with exponential backoff
-In order to create resilient microservices, you need to handle possible HTTP failure scenarios. For that purpose, you could create your own implementation of retries with exponential backoff.
+To create resilient microservices, you need to handle possible HTTP failure scenarios. One way of handling those failures, although not recommended, is to create your own implementation of retries with exponential backoff.
-In addition to handling temporal resource unavailability, the exponential backoff also needs to take into account that the cloud provider might throttle availability of resources to prevent usage overload. For example, creating too many connection requests very quickly might be viewed as a Denial of Service ([DoS](https://en.wikipedia.org/wiki/Denial-of-service_attack)) attack by the cloud provider. As a result, you need to provide a mechanism to scale back connection requests when a capacity threshold has been encountered.
+**Important note:** This section shows you how you could create your own custom code to implement HTTP call retries. However, it is not recommended to do it by your own but to use more powerful and reliable while simpler to use mechanisms, such as `HttpClientFactory` with Polly, available since .NET Core 2.1. Those recommended approaches are explained in the next sections.
-As an initial exploration, you could implement your own code with a utility class for exponential backoff as in [RetryWithExponentialBackoff.cs](https://gist.github.com/CESARDELATORRE/6d7f647b29e55fdc219ee1fd2babb260), plus code like the following (which is also available on a [GitHub repo](https://gist.github.com/CESARDELATORRE/d80c6423a1aebaffaf387469f5194f5b)).
+As an initial exploration, you could implement your own code with a utility class for exponential backoff as in [RetryWithExponentialBackoff.cs](https://gist.github.com/CESARDELATORRE/6d7f647b29e55fdc219ee1fd2babb260), plus code like the following (which is also available at this [GitHub repo](https://gist.github.com/CESARDELATORRE/d80c6423a1aebaffaf387469f5194f5b)).
```csharp
public sealed class RetryWithExponentialBackoff
@@ -107,9 +107,11 @@ public async Task GetCatalogItems(int page,int take, int? brand, int? t
}
```
-However, this code is suitable only as a proof of concept. The next topic explains how to use more sophisticated and proven libraries.
+Remember that this code is suitable only as a proof of concept.
+The next sections explain how to use more sophisticated approaches while simpler, by using HttpClientFactory.
+HttpClientFactory is available since .NET Core 2.1, with proven resiliency libraries like Polly.
>[!div class="step-by-step"]
[Previous](implement-resilient-entity-framework-core-sql-connections.md)
-[Next](implement-http-call-retries-exponential-backoff-polly.md)
+[Next](use-httpclientfactory-to-implement-resilient-http-requests.md)
\ No newline at end of file
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md b/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md
index 25eda515ffd6a..2c43e9c6b3f41 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md
@@ -3,11 +3,11 @@ title: Handling partial failure
description: .NET Microservices Architecture for Containerized .NET Applications | Handling partial failure
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 05/26/2017
+ms.date: 06/08/2018
---
# Handling partial failure
-In distributed systems like microservices-based applications, there is an ever-present risk of partial failure. For instance, a single microservice/container can fail or might not be available to respond for a short time, or a single VM or server can crash. Since clients and services are separate processes, a service might not be able to respond in a timely way to a client’s request. The service might be overloaded and responding extremely slowly to requests, or might simply not be accessible for a short time because of network issues.
+In distributed systems like microservices-based applications, there is an ever-present risk of partial failure. For instance, a single microservice/container can fail or might not be available to respond for a short time, or a single VM or server can crash. Since clients and services are separate processes, a service might not be able to respond in a timely way to a client’s request. The service might be overloaded and responding extremely slowly to requests or might simply not be accessible for a short time because of network issues.
For example, consider the Order details page from the eShopOnContainers sample application. If the ordering microservice is unresponsive when the user tries to submit an order, a bad implementation of the client process (the MVC web application)—for example, if the client code were to use synchronous RPCs with no timeout—would block threads indefinitely waiting for a response. In addition to creating a bad user experience, every unresponsive wait consumes or blocks a thread, and threads are extremely valuable in highly scalable applications. If there are many blocked threads, eventually the application’s runtime can run out of threads. In that case, the application can become globally unresponsive instead of just partially unresponsive, as show in Figure 10-1.
@@ -21,7 +21,7 @@ In a large microservices-based application, any partial failure can be amplified
**Figure 10-2**. The impact of having an incorrect design featuring long chains of HTTP requests
-Intermittent failure is virtually guaranteed in a distributed and cloud based system, even if every dependency itself has excellent availability. This should be a fact you need to consider.
+Intermittent failure is guaranteed in a distributed and cloud-based system, even if every dependency itself has excellent availability. It is fact you need to consider.
If you do not design and implement techniques to ensure fault tolerance, even small downtimes can be amplified. As an example, 50 dependencies each with 99.99% of availability would result in several hours of downtime each month because of this ripple effect. When a microservice dependency fails while handling a high volume of requests, that failure can quickly saturate all available request threads in each service and crash the whole application.
@@ -29,7 +29,7 @@ If you do not design and implement techniques to ensure fault tolerance, even sm
**Figure 10-3**. Partial failure amplified by microservices with long chains of synchronous HTTP calls
-To minimize this problem, in the section "*Asynchronous microservice integration enforce microservice’s autonomy*” (in the architecture chapter), we encouraged you to use asynchronous communication across the internal microservices. We briefly explain more in the next section.
+To minimize this problem, in the section "*Asynchronous microservice integration enforce microservice’s autonomy*” (in the architecture chapter), this guidance encourages you to use asynchronous communication across the internal microservices.
In addition, it is essential that you design your microservices and client applications to handle partial failures—that is, to build resilient microservices and client applications.
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md
index 06ac34b261029..b1e5009a78a07 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md
@@ -1,167 +1,98 @@
---
title: Implementing the Circuit Breaker pattern
-description: .NET Microservices Architecture for Containerized .NET Applications | Implementing the Circuit Breaker pattern
+description: .NET Microservices Architecture for Containerized .NET Applications | Implement the Circuit Breaker pattern as a complementary system to Http retries
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 11/12/2017
+ms.date: 07/03/2018
---
-# Implementing the Circuit Breaker pattern
-As noted earlier, you should handle faults that might take a variable amount of time to recover from, as might happen when you try to connect to a remote service or resource. Handling this type of fault can improve the stability and resiliency of an application.
+# Implement the Circuit Breaker pattern
-In a distributed environment, calls to remote resources and services can fail due to transient faults, such as slow network connections and timeouts, or if resources are being slow or are temporarily unavailable. These faults typically correct themselves after a short time, and a robust cloud application should be prepared to handle them by using a strategy like the Retry pattern.
+As noted earlier, you should handle faults that might take a variable amount of time to recover from, as it might happen when you try to connect to a remote service or resource. Handling this type of fault can improve the stability and resiliency of an application.
-However, there can also be situations where faults are due to unanticipated events that might take much longer to fix. These faults can range in severity from a partial loss of connectivity to the complete failure of a service. In these situations, it might be pointless for an application to continually retry an operation that is unlikely to succeed. Instead, the application should be coded to accept that the operation has failed and handle the failure accordingly.
+In a distributed environment, calls to remote resources and services can fail due to transient faults, such as slow network connections and timeouts, or if resources are being slow or are temporarily unavailable. These faults typically correct themselves after a short time, and a robust cloud application should be prepared to handle them by using a strategy like the "Retry pattern".
-The Circuit Breaker pattern has a different purpose than the Retry pattern. The Retry pattern enables an application to retry an operation in the expectation that the operation will eventually succeed. The Circuit Breaker pattern prevents an application from performing an operation that is likely to fail. An application can combine these two patterns by using the Retry pattern to invoke an operation through a circuit breaker. However, the retry logic should be sensitive to any exceptions returned by the circuit breaker, and it should abandon retry attempts if the circuit breaker indicates that a fault is not transient.
+However, there can also be situations where faults are due to unanticipated events that might take much longer to fix. These faults can range in severity from a partial loss of connectivity to the complete failure of a service. In these situations, it might be pointless for an application to continually retry an operation that is unlikely to succeed.
-## Implementing a Circuit Breaker pattern with Polly
+Instead, the application should be coded to accept that the operation has failed and handle the failure accordingly.
-As when implementing retries, the recommended approach for circuit breakers is to take advantage of proven .NET libraries like Polly.
+Using Http retries carelessly could result in creating a Denial of Service ([DoS](https://en.wikipedia.org/wiki/Denial-of-service_attack)) attack within your own software. As a microservice fails or performs slowly, multiple clients might repeatedly retry failed requests. That creates a dangerous risk of exponentially increasing traffic targeted at the failing service.
-The eShopOnContainers application uses the Polly Circuit Breaker policy when implementing HTTP retries. In fact, the application applies both policies to the ResilientHttpClient utility class. Whenever you use an object of type ResilientHttpClient for HTTP requests (from eShopOnContainers), you will be applying both those policies, but you could add additional policies, too.
+Therefore, you need some kind of defense barrier so the retries stop requests when it is not worth to keep trying. That defense barrier is precisely the circuit breaker.
-The only addition here to the code used for HTTP call retries is the code where you add the Circuit Breaker policy to the list of policies to use, as shown at the end of the following code:
+The Circuit Breaker pattern has a different purpose than the "Retry pattern". The "Retry pattern" enables an application to retry an operation in the expectation that the operation will eventually succeed. The Circuit Breaker pattern prevents an application from performing an operation that is likely to fail. An application can combine these two patterns. However, the retry logic should be sensitive to any exception returned by the circuit breaker, and it should abandon retry attempts if the circuit breaker indicates that a fault is not transient.
-```csharp
-public ResilientHttpClient CreateResilientHttpClient()
- => new ResilientHttpClient(CreatePolicies(), _logger);
+## Implement Circuit Breaker pattern with HttpClientFactory and Polly
-private Policy[] CreatePolicies()
- => new Policy[]
- {
- Policy.Handle()
- .WaitAndRetryAsync(
- // number of retries
- 6,
- // exponential backofff
- retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
- // on retry
- (exception, timeSpan, retryCount, context) =>
- {
- var msg = $"Retry {retryCount} implemented with Polly RetryPolicy " +
- $"of {context.PolicyKey} " +
- $"at {context.ExecutionKey}, " +
- $"due to: {exception}.";
- _logger.LogWarning(msg);
- _logger.LogDebug(msg);
- }),
- Policy.Handle()
- .CircuitBreakerAsync(
- // number of exceptions before breaking circuit
- 5,
- // time circuit opened before retry
- TimeSpan.FromMinutes(1),
- (exception, duration) =>
- {
- // on circuit opened
- _logger.LogTrace("Circuit breaker opened");
- },
- () =>
- {
- // on circuit closed
- _logger.LogTrace("Circuit breaker reset");
- })
- };
-}
-```
+As when implementing retries, the recommended approach for circuit breakers is to take advantage of proven .NET libraries like Polly and its native integration with HttpClientFactory.
-The code adds a policy to the HTTP wrapper. That policy defines a circuit breaker that opens when the code detects the specified number of consecutive exceptions (exceptions in a row), as passed in the exceptionsAllowedBeforeBreaking parameter (5 in this case). When the circuit is open, HTTP requests do not work, but an exception is raised.
+Adding a circuit breaker policy into your HttpClientFactory outgoing middleware pipeline is as simple as adding a single incremental piece of code to what you already have when using HttpClientFactory.
-Circuit breakers should also be used to redirect requests to a fallback infrastructure if you might have issues in a particular resource that is deployed in a different environment than the client application or service that is performing the HTTP call. That way, if there is an outage in the datacenter that impacts only your backend microservices but not your client applications, the client applications can redirect to the fallback services. Polly is planning a new policy to automate this [failover policy](https://github.com/App-vNext/Polly/wiki/Polly-Roadmap#failover-policy) scenario.
+The only addition here to the code used for HTTP call retries is the code where you add the Circuit Breaker policy to the list of policies to use, as shown in the following incremental code, part of the ConfigureServices() method.
-Of course, all those features are for cases where you are managing the failover from within the .NET code, as opposed to having it managed automatically for you by Azure, with location transparency.
+```csharp
+//ConfigureServices() - Startup.cs
+services.AddHttpClient()
+ .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to 5 minutes
+ .AddPolicyHandler(GetRetryPolicy())
+ .AddPolicyHandler(GetCircuitBreakerPolicy());
+```
-## Using the ResilientHttpClient utility class from eShopOnContainers
+The `AddPolicyHandler()`method is what adds policies to the HttpClient objects you will use. In this case, it is adding a Polly’s policy for a circuit breaker.
-You use the ResilientHttpClient utility class in a way similar to how you use the .NET HttpClient class. In the following example from the eShopOnContainers MVC web application (the OrderingService agent class used by OrderController), the ResilientHttpClient object is injected through the httpClient parameter of the constructor. Then the object is used to perform HTTP requests.
+In order to have a more modular approach, the Circuit Breaker Policy is defined in a separate method named GetCircuitBreakerPolicy(), as the following code.
```csharp
-public class OrderingService : IOrderingService
+static IAsyncPolicy GetCircuitBreakerPolicy()
{
- private IHttpClient _apiClient;
- private readonly string _remoteServiceBaseUrl;
- private readonly IOptionsSnapshot _settings;
- private readonly IHttpContextAccessor _httpContextAccesor;
-
- public OrderingService(IOptionsSnapshot settings,
- IHttpContextAccessor httpContextAccesor,
- IHttpClient httpClient)
- {
- _remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders";
- _settings = settings;
- _httpContextAccesor = httpContextAccesor;
- _apiClient = httpClient;
- }
-
- async public Task> GetMyOrders(ApplicationUser user)
- {
- var context = _httpContextAccesor.HttpContext;
- var token = await context.Authentication.GetTokenAsync("access_token");
- _apiClient.Inst.DefaultRequestHeaders.Authorization = new
- System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
- var ordersUrl = _remoteServiceBaseUrl;
- var dataString = await _apiClient.GetStringAsync(ordersUrl);
- var response = JsonConvert.DeserializeObject>(dataString);
- return response;
- }
-
- // Other methods ...
- async public Task CreateOrder(Order order)
- {
- var context = _httpContextAccesor.HttpContext;
- var token = await context.Authentication.GetTokenAsync("access_token");
- _apiClient.Inst.DefaultRequestHeaders.Authorization = new
- System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
- _apiClient.Inst.DefaultRequestHeaders.Add("x-requestid",
- order.RequestId.ToString());
- var ordersUrl = $"{_remoteServiceBaseUrl}/new";
- order.CardTypeId = 1;
- order.CardExpirationApiFormat();
- SetFakeIdToProducts(order);
- var response = await _apiClient.PostAsync(ordersUrl, order);
- response.EnsureSuccessStatusCode();
- }
+ return HttpPolicyExtensions
+ .HandleTransientHttpError()
+ .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}
```
-Whenever the \_apiClient member object is used, it internally uses the wrapper class with Polly policiesؙ—the Retry policy, the Circuit Breaker policy, and any other policy that you might want to apply from the Polly policies collection.
+In the code example above, the circuit breaker policy is configured so it breaks or opens the circuit when there have been five exceptions when retrying the Http requests. Then, 30 seconds will be the duration or the break.
-## Testing retries in eShopOnContainers
+Circuit breakers should also be used to redirect requests to a fallback infrastructure if you had issues in a particular resource that is deployed in a different environment than the client application or service that is performing the HTTP call. That way, if there is an outage in the datacenter that impacts only your backend microservices but not your client applications, the client applications can redirect to the fallback services. Polly is planning a new policy to automate this [failover policy](https://github.com/App-vNext/Polly/wiki/Polly-Roadmap#failover-policy) scenario.
-Whenever you start the eShopOnContainers solution in a Docker host, it needs to start multiple containers. Some of the containers are slower to start and initialize, like the SQL Server container. This is especially true the first time you deploy the eShopOnContainers application into Docker, because it needs to set up the images and the database. The fact that some containers start slower than others can cause the rest of the services to initially throw HTTP exceptions, even if you set dependencies between containers at the docker-compose level, as explained in previous sections. Those docker-compose dependencies between containers are just at the process level. The container’s entry point process might be started, but SQL Server might not be ready for queries. The result can be a cascade of errors, and the application can get an exception when trying to consume that particular container.
+All those features are for cases where you're managing the failover from within the .NET code, as opposed to having it managed automatically for you by Azure, with location transparency.
-You might also see this type of error on startup when the application is deploying to the cloud. In that case, orchestrators might be moving containers from one node or VM to another (that is, starting new instances) when balancing the number of containers across the cluster’s nodes.
+From a usage point of view, when using HttpClient, there’s no need to add anything new here because the code is the same than when using HttpClient with HttpClientFactory, as shown in previous sections.
+
+## Testing Http retries and circuit breakers in eShopOnContainers
-The way eShopOnContainers solves this issue is by using the Retry pattern we illustrated earlier. It is also why, when starting the solution, you might get log traces or warnings like the following:
-> "**Retry 1 implemented with Polly's RetryPolicy**, due to: System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.CurlException: Couldn't connect to server\\n at System.Net.Http.CurlHandler.ThrowIfCURLEError(CURLcode error)\\n at \[...\].
+Whenever you start the eShopOnContainers solution in a Docker host, it needs to start multiple containers. Some of the containers are slower to start and initialize, like the SQL Server container. This is especially true the first time you deploy the eShopOnContainers application into Docker, because it needs to set up the images and the database. The fact that some containers start slower than others can cause the rest of the services to initially throw HTTP exceptions, even if you set dependencies between containers at the docker-compose level, as explained in previous sections. Those docker-compose dependencies between containers are just at the process level. The container’s entry point process might be started, but SQL Server might not be ready for queries. The result can be a cascade of errors, and the application can get an exception when trying to consume that particular container.
+
+You might also see this type of error on startup when the application is deploying to the cloud. In that case, orchestrators might be moving containers from one node or VM to another (that is, starting new instances) when balancing the number of containers across the cluster’s nodes.
-## Testing the circuit breaker in eShopOnContainers
+The way 'eShopOnContainers' solves those issues when starting all the containers is by using the Retry pattern illustrated earlier.
-There are a few ways you can open the circuit and test it with eShopOnContainers.
+### Testing the circuit breaker in eShopOnContainers
+
+There are a few ways you can break/open the circuit and test it with eShopOnContainers.
One option is to lower the allowed number of retries to 1 in the circuit breaker policy and redeploy the whole solution into Docker. With a single retry, there is a good chance that an HTTP request will fail during deployment, the circuit breaker will open, and you get an error.
-Another option is to use custom middleware that is implemented in the `Basket` microservice. When this middleware is enabled, it catches all HTTP requests and returns status code 500. You can enable the middleware by making a GET request to the failing URI, like the following:
+Another option is to use custom middleware that is implemented in the Basket microservice. When this middleware is enabled, it catches all HTTP requests and returns status code 500. You can enable the middleware by making a GET request to the failing URI, like the following:
-- GET /failing
+- `GET http://localhost:5103/failing`
-This request returns the current state of the middleware. If the middleware is enabled, the request return status code 500. If the middleware is disabled, there is no response.
+This request returns the current state of the middleware. If the middleware is enabled, the request return status code 500. If the middleware is disabled, there is no response.
-- GET /failing?enable
+- `GET http://localhost:5103/failing?enable`
-This request enables the middleware.
+This request enables the middleware.
-- GET /failing?disable
+- `GET http://localhost:5103/failing?disable`
-This request disables the middleware.
+This request disables the middleware.
For instance, once the application is running, you can enable the middleware by making a request using the following URI in any browser. Note that the ordering microservice uses port 5103.
-http://localhost:5103/failing?enable
+`http://localhost:5103/failing?enable`
-You can then check the status using the URI [http://localhost:5103/failing](http://localhost:5103/failing), as shown in Figure 10-4.
+You can then check the status using the URI http://localhost:5103/failing, as shown in Figure 10-4.

@@ -169,9 +100,9 @@ You can then check the status using the URI [http://localhost:5103/failing](http
At this point, the Basket microservice responds with status code 500 whenever you call invoke it.
-Once the middleware is running, you can try making an order from the MVC web application. Because the requests fails, the circuit will open.
+Once the middleware is running, you can try making an order from the MVC web application. Because the requests fail, the circuit will open.
-In the following example, you can see that the MVC web application has a catch block in the logic for placing an order. If the code catches an open-circuit exception, it shows the user a friendly message telling them to wait.
+In the following example, you can see that the MVC web application has a catch block in the logic for placing an order. If the code catches an open-circuit exception, it shows the user a friendly message telling them to wait.
```csharp
public class CartController : Controller
@@ -180,8 +111,11 @@ public class CartController : Controller
public async Task Index()
{
try
- {
- //… Other code
+ {
+ var user = _appUserParser.Parse(HttpContext.User);
+ //Http requests using the Typed Client (Service Agent)
+ var vm = await _basketSvc.GetBasket(user);
+ return View(vm);
}
catch (BrokenCircuitException)
{
@@ -198,46 +132,23 @@ public class CartController : Controller
}
```
-Here’s a summary. The Retry policy tries several times to make the HTTP request and gets HTTP errors. When the number of tries reaches the maximum number set for the Circuit Breaker policy (in this case, 5), the application throws a BrokenCircuitException. The result is a friendly message, as shown in Figure 10-5.
+Here’s a summary. The Retry policy tries several times to make the HTTP request and gets HTTP errors. When the number of retries reaches the maximum number set for the Circuit Breaker policy (in this case, 5), the application throws a BrokenCircuitException. The result is a friendly message, as shown in Figure 10-5.

**Figure 10-5**. Circuit breaker returning an error to the UI
-You can implement different logic for when to open the circuit. Or you can try an HTTP request against a different back-end microservice if there is a fallback datacenter or redundant back-end system.
-
-Finally, another possibility for the CircuitBreakerPolicy is to use Isolate (which forces open and holds open the circuit) and Reset (which closes it again). These could be used to build a utility HTTP endpoint that invokes Isolate and Reset directly on the policy. Such an HTTP endpoint could also be used, suitably secured, in production for temporarily isolating a downstream system, such as when you want to upgrade it. Or it could trip the circuit manually to protect a downstream system you suspect to be faulting.
+You can implement different logic for when to open/break the circuit. Or you can try an HTTP request against a different back-end microservice if there is a fallback datacenter or redundant back-end system.
-## Adding a jitter strategy to the retry policy
+Finally, another possibility for the `CircuitBreakerPolicy` is to use `Isolate` (which forces open and holds open the circuit) and `Reset` (which closes it again). These could be used to build a utility HTTP endpoint that invokes Isolate and Reset directly on the policy. Such an HTTP endpoint could also be used, suitably secured, in production for temporarily isolating a downstream system, such as when you want to upgrade it. Or it could trip the circuit manually to protect a downstream system you suspect to be faulting.
-A regular Retry policy can impact your system in cases of high concurrency and scalability and under high contention. To overcome peaks of similar retries coming from many clients in case of partial outages, a good workaround is to add a jitter strategy to the retry algorithm/policy. This can improve the overall performance of the end-to-end system by adding randomness to the exponential backoff. This spreads out the spikes when issues arise. When you use Polly, code to implement jitter could look like the following example:
-
-```csharp
-Random jitterer = new Random();
-Policy.Handle() // etc
- .WaitAndRetry(5, // exponential back-off plus some jitter
- retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
- + TimeSpan.FromMilliseconds(jitterer.Next(0, 100))
- );
-```
## Additional resources
-- **Retry pattern**
- [*https://docs.microsoft.com/azure/architecture/patterns/retry*](https://docs.microsoft.com/azure/architecture/patterns/retry)
-
-- **Connection Resiliency** (Entity Framework Core)
- [*https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency*](https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency)
-
-- **Polly** (.NET resilience and transient-fault-handling library)
- [*https://github.com/App-vNext/Polly*](https://github.com/App-vNext/Polly)
- **Circuit Breaker pattern**
[*https://docs.microsoft.com/azure/architecture/patterns/circuit-breaker*](https://docs.microsoft.com/azure/architecture/patterns/circuit-breaker)
-- **Marc Brooker. Jitter: Making Things Better With Randomness**
- https://brooker.co.za/blog/2015/03/21/backoff.html
-
>[!div class="step-by-step"]
[Previous](implement-http-call-retries-exponential-backoff-polly.md)
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md
index 15ce408ad139e..05f9fb2b2b5c3 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md
@@ -1,169 +1,87 @@
---
-title: Implementing HTTP call retries with exponential backoff with Polly
-description: .NET Microservices Architecture for Containerized .NET Applications | Implementing HTTP call retries with exponential backoff with Polly
+title: Implement HTTP call retries with exponential backoff with Polly
+description: Learn how to handle HTTP failures with Polly and HttpClientFactory
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 05/26/2017
+ms.date: 06/10/2018
---
-# Implementing HTTP call retries with exponential backoff with Polly
-The recommended approach for retries with exponential backoff is to take advantage of more advanced .NET libraries like the open source [Polly](https://github.com/App-vNext/Polly) library.
+# Implement HTTP call retries with exponential backoff with HttpClientFactory and Polly policies
-Polly is a .NET library that provides resilience and transient-fault handling capabilities. You can implement those capabilities easily by applying Polly policies such as Retry, Circuit Breaker, Bulkhead Isolation, Timeout, and Fallback. Polly targets .NET 4.x and the .NET Standard version 1.0 (which supports .NET Core).
+The recommended approach for retries with exponential backoff is to take advantage of more advanced .NET libraries like the open-source [Polly library](https://github.com/App-vNext/Polly).
-The Retry policy in Polly is the approach used in eShopOnContainers when implementing HTTP retries. You can implement an interface so you can inject either standard HttpClient functionality or a resilient version of HttpClient using Polly, depending on what retry policy configuration you want to use.
+Polly is a .NET library that provides resilience and transient-fault handling capabilities. You can implement those capabilities by applying Polly policies such as Retry, Circuit Breaker, Bulkhead Isolation, Timeout, and Fallback. Polly targets .NET 4.x and the .NET Standard Library 1.0 (which supports .NET Core).
-The following example shows the interface implemented in eShopOnContainers.
+However, using Polly’s library with your own custom code with HttpClient can be significantly complex. In the original version of eShopOnContainers, there was a [ResilientHttpClient building-block](https://github.com/dotnet-architecture/eShopOnContainers/blob/master/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs) based on Polly. But with the release of HttpClientFactory, resilient Http communication has become much simpler to implement, so that building-block was deprecated from eShopOnContainers.
-```csharp
-public interface IHttpClient
-{
- Task GetStringAsync(string uri, string authorizationToken = null,
- string authorizationMethod = "Bearer");
- Task PostAsync(string uri, T item,
- string authorizationToken = null, string requestId = null,
- string authorizationMethod = "Bearer");
+The following steps show how you can use Http retries with Polly integrated into HttpClientFactory, which is explained in the previous section.
- Task DeleteAsync(string uri,
- string authorizationToken = null, string requestId = null,
- string authorizationMethod = "Bearer");
+**Reference the ASP.NET Core 2.1 packages**
- // Other methods ...
-}
-```
+Your project has to be using the ASP.NET Core 2.1 packages from NuGet. You typically need the `AspNetCore` metapackage, and the extension package `Microsoft.Extensions.Http.Polly`.
+
+**Configure a client with Polly’s Retry policy, in Startup**
-You can use the standard implementation if you do not want to use a resilient mechanism, as when you are developing or testing simpler approaches. The following code shows the standard HttpClient implementation allowing requests with authentication tokens as an optional case.
+As shown in previous sections, you need to define a named or typed client HttpClient configuration in your standard Startup.ConfigureServices(...) method, but now, you add incremental code specifying the policy for the Http retries with exponential backoff, as below:
```csharp
-public class StandardHttpClient : IHttpClient
-{
- private HttpClient _client;
- private ILogger _logger;
-
- public StandardHttpClient(ILogger logger)
- {
- _client = new HttpClient();
- _logger = logger;
- }
-
- public async Task GetStringAsync(string uri,
- string authorizationToken = null,
- string authorizationMethod = "Bearer")
- {
- var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
- if (authorizationToken != null)
- {
- requestMessage.Headers.Authorization =
- new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
- }
- var response = await _client.SendAsync(requestMessage);
- return await response.Content.ReadAsStringAsync();
- }
-
- public async Task PostAsync(string uri, T item,
- string authorizationToken = null, string requestId = null,
- string authorizationMethod = "Bearer")
- {
- // Rest of the code and other Http methods ...
+//ConfigureServices() - Startup.cs
+services.AddHttpClient()
+ .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes
+ .AddPolicyHandler(GetRetryPolicy());
```
-The interesting implementation is to code another, similar class, but using Polly to implement the resilient mechanisms you want to use—in the following example, retries with exponential backoff.
+The **AddPolicyHandler()** method is what adds policies to the `HttpClient` objects you will use. In this case, it is adding a Polly’s policy for Http Retries with exponential backoff.
+
+In order to have a more modular approach, the Http Retry Policy can be defined in a separate method within the ConfigureServices() method, as the following code.
```csharp
-public class ResilientHttpClient : IHttpClient
+static IAsyncPolicy GetRetryPolicy()
{
- private HttpClient _client;
- private PolicyWrap _policyWrapper;
- private ILogger _logger;
-
- public ResilientHttpClient(Policy[] policies,
- ILogger logger)
- {
- _client = new HttpClient();
- _logger = logger;
- // Add Policies to be applied
- _policyWrapper = Policy.WrapAsync(policies);
- }
-
- private Task HttpInvoker(Func> action)
- {
- // Executes the action applying all
- // the policies defined in the wrapper
- return _policyWrapper.ExecuteAsync(() => action());
- }
-
- public Task GetStringAsync(string uri,
- string authorizationToken = null,
- string authorizationMethod = "Bearer")
- {
- return HttpInvoker(async () =>
- {
- var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
- // The Token's related code eliminated for clarity in code snippet
- var response = await _client.SendAsync(requestMessage);
- return await response.Content.ReadAsStringAsync();
- });
- }
- // Other Http methods executed through HttpInvoker so it applies Polly policies
- // ...
+ return HttpPolicyExtensions
+ .HandleTransientHttpError()
+ .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
+ .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,
+ retryAttempt)));
}
```
-With Polly, you define a Retry policy with the number of retries, the exponential backoff configuration, and the actions to take when there is an HTTP exception, such as logging the error. In this case, the policy is configured so it will try the number of times specified when registering the types in the IoC container. Because of the exponential backoff configuration, whenever the code detects an HttpRequest exception, it retries the Http request after waiting an amount of time that increases exponentially depending on how the policy was configured.
+With Polly, you can define a Retry policy with the number of retries, the exponential backoff configuration, and the actions to take when there is an HTTP exception, such as logging the error. In this case, the policy is configured to try six times with an exponential retry, starting at two seconds.
+
+so it will try six times and the seconds between each retry will be exponential, starting on two seconds.
-The important method is HttpInvoker, which is what makes HTTP requests throughout this utility class. That method internally executes the HTTP request with \_policyWrapper.ExecuteAsync, which takes into account the retry policy.
+### Adding a jitter strategy to the retry policy
-In eShopOnContainers you specify Polly policies when registering the types at the IoC container, as in the following code from the [MVC web app at the startup.cs](https://github.com/dotnet-architecture/eShopOnContainers/blob/master/src/Web/WebMVC/Startup.cs) class.
+A regular Retry policy can impact your system in cases of high concurrency and scalability and under high contention. To overcome peaks of similar retries coming from many clients in case of partial outages, a good workaround is to add a jitter strategy to the retry algorithm/policy. This can improve the overall performance of the end-to-end system by adding randomness to the exponential backoff. This spreads out the spikes when issues arise. When you use a plain Polly policy, code to implement jitter could look like the following example:
```csharp
-// Startup.cs class
-if (Configuration.GetValue("UseResilientHttp") == bool.TrueString)
-{
- services.AddTransient();
- services.AddSingleton(sp =>
- sp.GetService().
- CreateResilientHttpClient());
-}
-else
-{
- services.AddSingleton();
-}
+Random jitterer = new Random();
+Policy
+ .Handle() // etc
+ .WaitAndRetry(5, // exponential back-off plus some jitter
+ retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
+ + TimeSpan.FromMilliseconds(jitterer.Next(0, 100))
+ );
```
-Note that the IHttpClient objects are instantiated as singleton instead of as transient so that TCP connections are used efficiently by the service and [an issue with sockets](https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/) will not occur.
+## Additional resources
-But the important point about resiliency is that you apply the Polly WaitAndRetryAsync policy within ResilientHttpClientFactory in the CreateResilientHttpClient method, as shown in the following code:
+- **Retry pattern**
+ [*https://docs.microsoft.com/azure/architecture/patterns/retry*](https://docs.microsoft.com/azure/architecture/patterns/retry)
+
+- **Polly and HttpClientFactory**
+ [*https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory*](https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory)
+
+- **Polly (.NET resilience and transient-fault-handling library)**
+
+ [*https://github.com/App-vNext/Polly*](https://github.com/App-vNext/Polly)
+
+- **Marc Brooker. Jitter: Making Things Better With Randomness**
+
+ [*https://brooker.co.za/blog/2015/03/21/backoff.html*](https://brooker.co.za/blog/2015/03/21/backoff.html)
-```csharp
-public ResilientHttpClient CreateResilientHttpClient()
- => new ResilientHttpClient(CreatePolicies(), _logger);
-
-// Other code
-private Policy[] CreatePolicies()
- => new Policy[]
- {
- Policy.Handle()
- .WaitAndRetryAsync(
- // number of retries
- 6,
- // exponential backoff
- retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
- // on retry
- (exception, timeSpan, retryCount, context) =>
- {
- var msg = $"Retry {retryCount} implemented with Pollys RetryPolicy " +
- $"of {context.PolicyKey} " +
- $"at {context.ExecutionKey}, " +
- $"due to: {exception}.";
- _logger.LogWarning(msg);
- _logger.LogDebug(msg);
- }),
- }
-```
>[!div class="step-by-step"]
-[Previous](implement-custom-http-call-retries-exponential-backoff.md)
+[Previous](explore-custom-http-call-retries-exponential-backoff.md)
[Next](implement-circuit-breaker-pattern.md)
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md
index 374bf4c5ae6f1..dc26e59876198 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md
@@ -1,11 +1,11 @@
---
-title: Implementing resilient Entity Framework Core SQL connections
-description: .NET Microservices Architecture for Containerized .NET Applications | Implementing resilient Entity Framework Core SQL connections
+title: Implement resilient Entity Framework Core SQL connections
+description: .NET Microservices Architecture for Containerized .NET Applications | Implement resilient Entity Framework Core SQL connections. This technique is especially important when using Azure SQL Database in the cloud.
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 05/26/2017
+ms.date: 06/08/2018
---
-# Implementing resilient Entity Framework Core SQL connections
+# Implement resilient Entity Framework Core SQL connections
For Azure SQL DB, Entity Framework Core already provides internal database connection resiliency and retry logic. But you need to enable the Entity Framework execution strategy for each DbContext connection if you want to have [resilient EF Core connections](https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency).
@@ -19,13 +19,13 @@ public class Startup
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// ...
- services.AddDbContext(options =>
+ services.AddDbContext(options =>
{
options.UseSqlServer(Configuration["ConnectionString"],
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
- maxRetryCount: 5,
+ maxRetryCount: 10,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
});
@@ -37,7 +37,7 @@ public class Startup
## Execution strategies and explicit transactions using BeginTransaction and multiple DbContexts
-When retries are enabled in EF Core connections, each operation you perform using EF Core becomes its own retriable operation. Each query and each call to SaveChanges will be retried as a unit if a transient failure occurs.
+When retries are enabled in EF Core connections, each operation you perform using EF Core becomes its own retryable operation. Each query and each call to SaveChanges will be retried as a unit if a transient failure occurs.
However, if your code initiates a transaction using BeginTransaction, you are defining your own group of operations that need to be treated as a unit—everything inside the transaction has be rolled back if a failure occurs. You will see an exception like the following if you attempt to execute that transaction when using an EF execution strategy (retry policy) and you include several SaveChanges calls from multiple DbContexts in the transaction.
@@ -79,13 +79,15 @@ The first DbContext is \_catalogContext and the second DbContext is within the \
## Additional resources
+- **EF Connection Resiliency** (Entity Framework Core)
+ [*https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency*](https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency)
+
- **Connection Resiliency and Command Interception with the Entity Framework**
[*https://docs.microsoft.com/azure/architecture/patterns/category/resiliency*](https://docs.microsoft.com/azure/architecture/patterns/category/resiliency)
- **Cesar de la Torre. Using Resilient Entity Framework Core Sql Connections and Transactions**
-
>[!div class="step-by-step"]
[Previous](implement-retries-exponential-backoff.md)
-[Next](implement-custom-http-call-retries-exponential-backoff.md)
+[Next]explore-custom-http-call-retries-exponential-backoff.md)
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md
index 9bb966defcfc3..9abd680f524af 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md
@@ -1,11 +1,11 @@
---
-title: Implementing retries with exponential backoff
+title: Implement retries with exponential backoff
description: .NET Microservices Architecture for Containerized .NET Applications | Implementing retries with exponential backoff
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 05/26/2017
+ms.date: 06/08/2018
---
-# Implementing retries with exponential backoff
+# Implement retries with exponential backoff
[*Retries with exponential backoff*](https://docs.microsoft.com/azure/architecture/patterns/retry) is a technique that attempts to retry an operation, with an exponentially increasing wait time, until a maximum retry count has been reached (the [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff)). This technique embraces the fact that cloud resources might intermittently be unavailable for more than a few seconds for any reason. For example, an orchestrator might be moving a container to another node in a cluster for load balancing. During that time, some requests might fail. Another example could be a database like SQL Azure, where a database can be moved to another server for load balancing, causing the database to be unavailable for a few seconds.
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/index.md b/docs/standard/microservices-architecture/implement-resilient-applications/index.md
index b0c94b3a6de9a..2094508b515b4 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/index.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/index.md
@@ -3,13 +3,13 @@ title: Implementing Resilient Applications
description: .NET Microservices Architecture for Containerized .NET Applications | Implementing Resilient Applications
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 05/26/2017
+ms.date: 06/08/2018
---
# Implementing Resilient Applications
-*Your microservice and cloud based applications must embrace the partial failures that will certainly occur eventually. You need to design your application so it will be resilient to those partial failures.*
+*Your microservice and cloud-based applications must embrace the partial failures that will certainly occur eventually. You need to design your application so it will be resilient to those partial failures.*
-Resiliency is the ability to recover from failures and continue to function. It is not about avoiding failures, but accepting the fact that failures will happen and responding to them in a way that avoids downtime or data loss. The goal of resiliency is to return the application to a fully functioning state after a failure.
+Resiliency is the ability to recover from failures and continue to function. It is not about avoiding failures but accepting the fact that failures will happen and responding to them in a way that avoids downtime or data loss. The goal of resiliency is to return the application to a fully functioning state after a failure.
It is challenging enough to design and deploy a microservices-based application. But you also need to keep your application running in an environment where some sort of failure is certain. Therefore, your application should be resilient. It should be designed to cope with partial failures, like network outages or nodes or VMs crashing in the cloud. Even microservices (containers) being moved to a different node within a cluster can cause intermittent short failures within the application.
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/media/image3.5.png b/docs/standard/microservices-architecture/implement-resilient-applications/media/image3.5.png
new file mode 100644
index 0000000000000..21a16ed5c5bea
Binary files /dev/null and b/docs/standard/microservices-architecture/implement-resilient-applications/media/image3.5.png differ
diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md b/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md
index 4e1434a7a79e1..ec3bdc96488c5 100644
--- a/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md
+++ b/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md
@@ -3,7 +3,7 @@ title: Strategies for handling partial failure
description: .NET Microservices Architecture for Containerized .NET Applications | Strategies for handling partial failure
author: CESARDELATORRE
ms.author: wiwagn
-ms.date: 05/26/2017
+ms.date: 06/08/2018
---
# Strategies for handling partial failure
@@ -19,7 +19,7 @@ Strategies for dealing with partial failures include the following.
**Provide fallbacks**. In this approach, the client process performs fallback logic when a request fails, such as returning cached data or a default value. This is an approach suitable for queries, and is more complex for updates or commands.
-**Limit the number of queued requests**. Clients should also impose an upper bound on the number of outstanding requests that a client microservice can send to a particular service. If the limit has been reached, it is probably pointless to make additional requests, and those attempts should fail immediately. In terms of implementation, the Polly [Bulkhead Isolation](https://github.com/App-vNext/Polly/wiki/Bulkhead) policy can be used to fulfil this requirement. This approach is essentially a parallelization throttle with as the implementation. It also permits a "queue" outside the bulkhead. You can proactively shed excess load even before execution (for example, because capacity is deemed full). This makes its response to certain failure scenarios faster than a circuit breaker would be, since the circuit breaker waits for the failures. The BulkheadPolicy object in Polly exposes how full the bulkhead and queue are, and offers events on overflow so can also be used to drive automated horizontal scaling.
+**Limit the number of queued requests**. Clients should also impose an upper bound on the number of outstanding requests that a client microservice can send to a particular service. If the limit has been reached, it is probably pointless to make additional requests, and those attempts should fail immediately. In terms of implementation, the Polly [Bulkhead Isolation](https://github.com/App-vNext/Polly/wiki/Bulkhead) policy can be used to fulfill this requirement. This approach is essentially a parallelization throttle with