@@ -7,25 +7,39 @@ namespace Coverlet.Tracker
77{
88 public static class CoverageTracker
99 {
10- private static Dictionary < string , Dictionary < string , int > > _events ;
10+ private static List < Dictionary < string , Dictionary < string , int > > > _events ;
11+
12+ [ ThreadStatic ]
13+ private static Dictionary < string , Dictionary < string , int > > t_events ;
1114
1215 [ ExcludeFromCodeCoverage ]
1316 static CoverageTracker ( )
1417 {
15- _events = new Dictionary < string , Dictionary < string , int > > ( ) ;
18+ _events = new List < Dictionary < string , Dictionary < string , int > > > ( ) ;
1619 AppDomain . CurrentDomain . ProcessExit += new EventHandler ( CurrentDomain_ProcessExit ) ;
1720 AppDomain . CurrentDomain . DomainUnload += new EventHandler ( CurrentDomain_ProcessExit ) ;
1821 }
1922
2023 [ ExcludeFromCodeCoverage ]
2124 public static void MarkExecuted ( string file , string evt )
2225 {
23- lock ( _events )
26+ if ( t_events == null )
27+ {
28+ t_events = new Dictionary < string , Dictionary < string , int > > ( ) ;
29+ lock ( _events )
30+ {
31+ _events . Add ( t_events ) ;
32+ }
33+ }
34+
35+ // We are taking the lock only for synchronizing with CurrentDomain_ProcessExit event
36+ // but the lock should be fast as the thread shouldn't block before getting process exit event
37+ lock ( t_events )
2438 {
25- if ( ! _events . TryGetValue ( file , out var fileEvents ) )
39+ if ( ! t_events . TryGetValue ( file , out var fileEvents ) )
2640 {
2741 fileEvents = new Dictionary < string , int > ( ) ;
28- _events . Add ( file , fileEvents ) ;
42+ t_events . Add ( file , fileEvents ) ;
2943 }
3044
3145 if ( ! fileEvents . TryGetValue ( evt , out var count ) )
@@ -42,16 +56,30 @@ public static void MarkExecuted(string file, string evt)
4256 [ ExcludeFromCodeCoverage ]
4357 public static void CurrentDomain_ProcessExit ( object sender , EventArgs e )
4458 {
59+ Dictionary < string , bool > encounteredFile = new Dictionary < string , bool > ( ) ;
60+
4561 lock ( _events )
4662 {
47- foreach ( var files in _events )
63+ foreach ( var localEvents in _events )
4864 {
49- using ( var fs = new FileStream ( files . Key , FileMode . Create ) )
50- using ( var sw = new StreamWriter ( fs ) )
65+ lock ( localEvents )
5166 {
52- foreach ( var evt in files . Value )
67+ foreach ( var files in localEvents )
5368 {
54- sw . WriteLine ( $ "{ evt . Key } ,{ evt . Value } ") ;
69+ FileMode mode = FileMode . Append ;
70+ if ( ! encounteredFile . TryGetValue ( files . Key , out bool b ) )
71+ {
72+ encounteredFile . Add ( files . Key , true ) ;
73+ mode = FileMode . Create ;
74+ }
75+ using ( var fs = new FileStream ( files . Key , mode ) )
76+ using ( var sw = new StreamWriter ( fs ) )
77+ {
78+ foreach ( var evt in files . Value )
79+ {
80+ sw . WriteLine ( $ "{ evt . Key } ,{ evt . Value } ") ;
81+ }
82+ }
5583 }
5684 }
5785 }
0 commit comments