You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
One common concern related to exceptions is that if exceptions are used for code that routinely fails, the performance of the implementation will be unacceptable. This is a valid concern. When a member throws an exception, its performance can be orders of magnitude slower. However, it is possible to achieve good performance while strictly adhering to the exception guidelines that disallow using error codes. Two patterns described in this section suggest ways to do this.
16
-
17
-
**X DO NOT** use error codes because of concerns that exceptions might affect performance negatively.
18
-
19
-
To improve performance, it is possible to use either the Tester-Doer Pattern or the Try-Parse Pattern, described in the next two sections.
20
-
21
-
## Tester-Doer Pattern
22
-
Sometimes performance of an exception-throwing member can be improved by breaking the member into two. Let’s look at the <xref:System.Collections.Generic.ICollection%601.Add%2A> method of the <xref:System.Collections.Generic.ICollection%601> interface.
23
-
24
-
```
25
-
ICollection<int> numbers = ...
26
-
numbers.Add(1);
27
-
```
28
-
29
-
The method `Add` throws if the collection is read-only. This can be a performance problem in scenarios where the method call is expected to fail often. One of the ways to mitigate the problem is to test whether the collection is writable before trying to add a value.
30
-
31
-
```
32
-
ICollection<int> numbers = ...
33
-
...
34
-
if(!numbers.IsReadOnly){
35
-
numbers.Add(1);
36
-
}
37
-
```
38
-
39
-
The member used to test a condition, which in our example is the property `IsReadOnly`, is referred to as the tester. The member used to perform a potentially throwing operation, the `Add` method in our example, is referred to as the doer.
40
-
41
-
**✓ CONSIDER** the Tester-Doer Pattern for members that might throw exceptions in common scenarios to avoid performance problems related to exceptions.
42
-
43
-
## Try-Parse Pattern
44
-
For extremely performance-sensitive APIs, an even faster pattern than the Tester-Doer Pattern described in the previous section should be used. The pattern calls for adjusting the member name to make a well-defined test case a part of the member semantics. For example, <xref:System.DateTime> defines a <xref:System.DateTime.Parse%2A> method that throws an exception if parsing of a string fails. It also defines a corresponding <xref:System.DateTime.TryParse%2A> method that attempts to parse, but returns false if parsing is unsuccessful and returns the result of a successful parsing using an `out` parameter.
45
-
46
-
```
47
-
public struct DateTime {
48
-
public static DateTime Parse(string dateTime){
49
-
...
50
-
}
51
-
public static bool TryParse(string dateTime, out DateTime result){
52
-
...
53
-
}
54
-
}
55
-
```
56
-
57
-
When using this pattern, it is important to define the try functionality in strict terms. If the member fails for any reason other than the well-defined try, the member must still throw a corresponding exception.
58
-
59
-
**✓ CONSIDER** the Try-Parse Pattern for members that might throw exceptions in common scenarios to avoid performance problems related to exceptions.
60
-
61
-
**✓ DO** use the prefix "Try" and Boolean return type for methods implementing this pattern.
62
-
63
-
**✓ DO** provide an exception-throwing member for each member using the Try-Parse Pattern.
*Reprinted by permission of Pearson Education, Inc. from [Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition](https://www.informit.com/store/framework-design-guidelines-conventions-idioms-and-9780321545619) by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by Addison-Wesley Professional as part of the Microsoft Windows Development Series.*
68
-
15
+
One common concern related to exceptions is that if exceptions are used for code that routinely fails, the performance of the implementation will be unacceptable. This is a valid concern. When a member throws an exception, its performance can be orders of magnitude slower. However, it is possible to achieve good performance while strictly adhering to the exception guidelines that disallow using error codes. Two patterns described in this section suggest ways to do this.
16
+
17
+
**X DO NOT** use error codes because of concerns that exceptions might affect performance negatively.
18
+
19
+
To improve performance, it is possible to use either the Tester-Doer Pattern or the Try-Parse Pattern, described in the next two sections.
20
+
21
+
## Tester-Doer Pattern
22
+
Sometimes performance of an exception-throwing member can be improved by breaking the member into two. Let’s look at the <xref:System.Collections.Generic.ICollection%601.Add%2A> method of the <xref:System.Collections.Generic.ICollection%601> interface.
23
+
24
+
```csharp
25
+
ICollection<int>numbers=...
26
+
numbers.Add(1);
27
+
```
28
+
29
+
The method `Add` throws if the collection is read-only. This can be a performance problem in scenarios where the method call is expected to fail often. One of the ways to mitigate the problem is to test whether the collection is writable before trying to add a value.
30
+
31
+
```csharp
32
+
ICollection<int>numbers=...
33
+
...
34
+
if (!numbers.IsReadOnly)
35
+
{
36
+
numbers.Add(1);
37
+
}
38
+
```
39
+
40
+
Thememberusedtotestacondition, whichinourexampleistheproperty `IsReadOnly`, isreferredtoasthetester. Thememberusedtoperformapotentiallythrowingoperation, the `Add` methodinourexample, isreferredtoasthedoer.
Forextremelyperformance-sensitiveAPIs, anevenfasterpatternthantheTester-DoerPatterndescribedintheprevioussectionshouldbeused. Thepatterncallsfor adjusting the member name to make a well-defined test case a part of the member semantics. For example, <xref:System.DateTime> defines a <xref:System.DateTime.Parse%2A> method that throws an exception if parsing of a string fails. It also defines a corresponding <xref:System.DateTime.TryParse%2A> method that attempts to parse, but returns false if parsing is unsuccessful and returns the result of a successful parsing using an `out` parameter.
When using this pattern, it is important to define the try functionality in strict terms. If the member fails for any reason other than the well-defined try, the member must still throw a corresponding exception.
62
+
63
+
**✓ CONSIDER** the Try-Parse Pattern for members that might throw exceptions in common scenarios to avoid performance problems related to exceptions.
64
+
65
+
**✓ DO** use the prefix "Try" and Boolean return type for methods implementing this pattern.
66
+
67
+
**✓ DO** provide an exception-throwing member for each member using the Try-Parse Pattern.
*Reprinted by permission of Pearson Education, Inc. from [Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition](https://www.informit.com/store/framework-design-guidelines-conventions-idioms-and-9780321545619) by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by Addison-Wesley Professional as part of the Microsoft Windows Development Series.*
0 commit comments