@@ -138,14 +138,14 @@ public async Task<string> Search(
138138 }
139139
140140 // Create tasks for parallel execution
141- var wordSearchTask = Task . Run ( ( ) => PerformWordSearch ( allFiles , searchTerms , version . Value ) ) ;
142- var semanticSearchTask = Task . Run ( ( ) => PerformSemanticSearch ( message , version ) ) ;
141+ var wordSearchTask = PerformWordSearchAsync ( allFiles , searchTerms , version . Value ) ;
142+ var semanticSearchTask = PerformSemanticSearchAsync ( message , version ) ;
143143
144144 // Wait for both tasks to complete
145- Task . WaitAll ( wordSearchTask , semanticSearchTask ) ;
145+ await Task . WhenAll ( wordSearchTask , semanticSearchTask ) ;
146146
147- var wordMatches = wordSearchTask . Result ;
148- var semanticMatches = semanticSearchTask . Result ;
147+ var wordMatches = await wordSearchTask ;
148+ var semanticMatches = await semanticSearchTask ;
149149
150150 // Create consolidated results
151151 var consolidatedResults = ConsolidateSearchResults ( semanticMatches , wordMatches ) ;
@@ -225,7 +225,7 @@ private List<ConsolidatedSearchResult> ConsolidateSearchResults(List<SemanticMat
225225 return sortedResults ;
226226 }
227227
228- private List < SearchResult > PerformWordSearch ( IEnumerable < string > allFiles , List < string > searchTerms , int version )
228+ private async Task < List < SearchResult > > PerformWordSearchAsync ( IEnumerable < string > allFiles , List < string > searchTerms , int version )
229229 {
230230 logger . LogInformation ( "[CslaCodeTool.PerformWordSearch] Starting word search for version {Version}" , version ) ;
231231 var results = new List < SearchResult > ( ) ;
@@ -243,7 +243,7 @@ private List<SearchResult> PerformWordSearch(IEnumerable<string> allFiles, List<
243243 if ( ! isCommon && ! isMatchingVersion )
244244 continue ;
245245
246- var content = File . ReadAllText ( file ) ;
246+ var content = await File . ReadAllTextAsync ( file ) ;
247247 // Document length as number of word tokens
248248 var docLength = GetDocumentLength ( content ) ;
249249 candidateDocs . Add ( ( relativePath . Replace ( "\\ " , "/" ) , content , docLength ) ) ;
@@ -365,15 +365,15 @@ private List<SearchResult> NormalizeWordSearchResults(List<SearchResult> results
365365 return normalizedResults ;
366366 }
367367
368- private List < SemanticMatch > PerformSemanticSearch ( string message , int ? version )
368+ private async Task < List < SemanticMatch > > PerformSemanticSearchAsync ( string message , int ? version )
369369 {
370370 logger . LogInformation ( "[CslaCodeTool.PerformSemanticSearch] Starting semantic search for version {Version}" , version ) ;
371371 var semanticMatches = new List < SemanticMatch > ( ) ;
372372
373373 if ( VectorStore != null && VectorStore . IsReady ( ) )
374374 {
375375 logger . LogInformation ( "[CslaCodeTool.PerformSemanticSearch] Performing semantic search" ) ;
376- var semanticResults = VectorStore . SearchAsync ( message , version , topK : 10 ) . GetAwaiter ( ) . GetResult ( ) ;
376+ var semanticResults = await VectorStore . SearchAsync ( message , version , topK : 10 ) ;
377377 semanticMatches = semanticResults . Select ( r => new SemanticMatch
378378 {
379379 FileName = r . FileName ,
@@ -493,15 +493,15 @@ private static int CountWordOccurrences(string content, string searchTerm)
493493
494494 if ( File . Exists ( filePath ) )
495495 {
496- var content = File . ReadAllText ( filePath ) ;
496+ var content = await File . ReadAllTextAsync ( filePath ) ;
497497 logger . LogInformation ( "[CslaCodeTool.Fetch] Successfully read file '{FileName}' ({Length} characters)" , fileName , content . Length ) ;
498498 return content ;
499499 }
500500 else
501501 {
502502 // File not found at exact path - check if there are version-specific alternatives
503503 var fileNameOnly = Path . GetFileName ( fileName ) ;
504- var matchingFiles = FindVersionSpecificFiles ( fileNameOnly ) ;
504+ var matchingFiles = await FindVersionSpecificFilesAsync ( fileNameOnly ) ;
505505
506506 if ( matchingFiles . Count > 1 )
507507 {
@@ -518,7 +518,7 @@ private static int CountWordOccurrences(string content, string searchTerm)
518518 {
519519 // Single match found in a version-specific folder
520520 var matchedFilePath = Path . Combine ( CodeSamplesPath , matchingFiles [ 0 ] ) ;
521- var content = File . ReadAllText ( matchedFilePath ) ;
521+ var content = await File . ReadAllTextAsync ( matchedFilePath ) ;
522522 logger . LogInformation ( "[CslaCodeTool.Fetch] Found single version-specific file '{FileName}', returning content ({Length} characters)" , matchingFiles [ 0 ] , content . Length ) ;
523523 return content ;
524524 }
@@ -551,16 +551,20 @@ private static int CountWordOccurrences(string content, string searchTerm)
551551 /// Searches for files with the given name across all version-specific subdirectories.
552552 /// Returns a list of relative paths (e.g., "v10/Command.md", "v9/Command.md").
553553 /// </summary>
554- private List < string > FindVersionSpecificFiles ( string fileName )
554+ private async Task < List < string > > FindVersionSpecificFilesAsync ( string fileName )
555555 {
556556 var results = new List < string > ( ) ;
557557
558558 try
559559 {
560560 // Get all .cs and .md files in the code samples directory
561- var allFiles = Directory . GetFiles ( CodeSamplesPath , "*.*" , SearchOption . AllDirectories )
562- . Where ( f => f . EndsWith ( ".cs" , StringComparison . OrdinalIgnoreCase ) ||
563- f . EndsWith ( ".md" , StringComparison . OrdinalIgnoreCase ) ) ;
561+ // Note: Directory.GetFiles is synchronous and doesn't have an async alternative
562+ // Running on thread pool to avoid blocking
563+ var allFiles = await Task . Run ( ( ) =>
564+ Directory . GetFiles ( CodeSamplesPath , "*.*" , SearchOption . AllDirectories )
565+ . Where ( f => f . EndsWith ( ".cs" , StringComparison . OrdinalIgnoreCase ) ||
566+ f . EndsWith ( ".md" , StringComparison . OrdinalIgnoreCase ) )
567+ . ToList ( ) ) ;
564568
565569 // Find files that match the requested file name
566570 foreach ( var file in allFiles )
0 commit comments