11using System ;
22using System . Diagnostics ;
33using System . Threading ;
4+ using Microsoft . VisualStudio . TestTools . UnitTesting ;
45
56namespace TensorFlowNET . UnitTest
67{
@@ -13,6 +14,7 @@ public class MultiThreadedUnitTestExecuter : IDisposable
1314 {
1415 public int ThreadCount { get ; }
1516 public Thread [ ] Threads { get ; }
17+ public Exception [ ] Exceptions { get ; }
1618 private readonly SemaphoreSlim barrier_threadstarted ;
1719 private readonly ManualResetEventSlim barrier_corestart ;
1820 private readonly SemaphoreSlim done_barrier2 ;
@@ -57,6 +59,7 @@ public MultiThreadedUnitTestExecuter(int threadCount)
5759 throw new ArgumentOutOfRangeException ( nameof ( threadCount ) ) ;
5860 ThreadCount = threadCount ;
5961 Threads = new Thread [ ThreadCount ] ;
62+ Exceptions = new Exception [ ThreadCount ] ;
6063 done_barrier2 = new SemaphoreSlim ( 0 , threadCount ) ;
6164 barrier_corestart = new ManualResetEventSlim ( ) ;
6265 barrier_threadstarted = new SemaphoreSlim ( 0 , threadCount ) ;
@@ -72,28 +75,53 @@ public void Run(params MultiThreadedTestDelegate[] workloads)
7275
7376 if ( ThreadCount == 1 )
7477 {
78+ Exception ex = null ;
7579 new Thread ( ( ) =>
7680 {
77- workloads [ 0 ] ( 0 ) ;
78- done_barrier2 . Release ( 1 ) ;
81+ try
82+ {
83+ workloads [ 0 ] ( 0 ) ;
84+ } catch ( Exception e )
85+ {
86+ if ( Debugger . IsAttached )
87+ throw ;
88+ ex = e ;
89+ } finally
90+ {
91+ done_barrier2 . Release ( 1 ) ;
92+ }
7993 } ) . Start ( ) ;
80-
94+
8195 done_barrier2 . Wait ( ) ;
96+
97+ if ( ex != null )
98+ throw new Exception ( $ "Thread 0 has failed: ", ex ) ;
99+
82100 PostRun ? . Invoke ( this ) ;
83101
84102 return ;
85103 }
86104
87105 //thread core
88- void ThreadCore ( MultiThreadedTestDelegate core , int threadid )
106+ Exception ThreadCore ( MultiThreadedTestDelegate core , int threadid )
89107 {
90108 barrier_threadstarted . Release ( 1 ) ;
91109 barrier_corestart . Wait ( ) ;
92-
93110 //workload
94- core ( threadid ) ;
111+ try
112+ {
113+ core ( threadid ) ;
114+ } catch ( Exception e )
115+ {
116+ if ( Debugger . IsAttached )
117+ throw ;
118+ return e ;
119+ } finally
120+ {
121+ done_barrier2 . Release ( 1 ) ;
122+ }
95123
96- done_barrier2 . Release ( 1 ) ;
124+ return null ;
97125 }
98126
99127 //initialize all threads
@@ -103,15 +131,15 @@ void ThreadCore(MultiThreadedTestDelegate core, int threadid)
103131 for ( int i = 0 ; i < ThreadCount ; i ++ )
104132 {
105133 var i_local = i ;
106- Threads [ i ] = new Thread ( ( ) => ThreadCore ( workload , i_local ) ) ;
134+ Threads [ i ] = new Thread ( ( ) => Exceptions [ i_local ] = ThreadCore ( workload , i_local ) ) ;
107135 }
108136 } else
109137 {
110138 for ( int i = 0 ; i < ThreadCount ; i ++ )
111139 {
112140 var i_local = i ;
113141 var workload = workloads [ i_local % workloads . Length ] ;
114- Threads [ i ] = new Thread ( ( ) => ThreadCore ( workload , i_local ) ) ;
142+ Threads [ i ] = new Thread ( ( ) => Exceptions [ i_local ] = ThreadCore ( workload , i_local ) ) ;
115143 }
116144 }
117145
@@ -126,6 +154,11 @@ void ThreadCore(MultiThreadedTestDelegate core, int threadid)
126154 //wait for threads to finish
127155 for ( int i = 0 ; i < ThreadCount ; i ++ ) done_barrier2 . Wait ( ) ;
128156
157+ //handle fails
158+ for ( int i = 0 ; i < ThreadCount ; i ++ )
159+ if ( Exceptions [ i ] != null )
160+ throw new Exception ( $ "Thread { i } has failed: ", Exceptions [ i ] ) ;
161+
129162 //checks after ended
130163 PostRun ? . Invoke ( this ) ;
131164 }
0 commit comments