1717using System . Text ;
1818using System . Threading ;
1919using System . Threading . Tasks ;
20+ using System . Windows . Forms ;
2021using Microsoft . Extensions . Configuration ;
2122using myoddweb . directorywatcher ;
2223using myoddweb . directorywatcher . interfaces ;
24+ using Nito . AsyncEx ;
2325
2426namespace AsyncToSyncCodeRoundtripSynchroniserMonitor
2527{
@@ -45,7 +47,7 @@ internal static class Global
4547
4648
4749
48- internal static readonly AsyncLockQueueDictionary FileOperationLocks = new AsyncLockQueueDictionary ( ) ;
50+ internal static readonly AsyncLockQueueDictionary < string > FileOperationLocks = new AsyncLockQueueDictionary < string > ( ) ;
4951 //internal static readonly AsyncLock FileOperationAsyncLock = new AsyncLock();
5052 }
5153#pragma warning restore S2223
@@ -227,7 +229,7 @@ await ConsoleWatch.OnAddedAsync
227229
228230
229231 //listen for the Ctrl+C
230- WaitForCtrlC ( ) ;
232+ await WaitForCtrlC ( ) ;
231233
232234 Console . WriteLine ( "Stopping..." ) ;
233235
@@ -241,7 +243,7 @@ await ConsoleWatch.OnAddedAsync
241243 }
242244 catch ( Exception ex )
243245 {
244- WriteException ( ex ) ;
246+ await WriteException ( ex ) ;
245247 }
246248 }
247249
@@ -306,36 +308,75 @@ private static IEnumerable<FileInfo> ProcessSubDirs(DirectoryInfo srcDirInfo, st
306308 } //foreach (var dirInfo in dirInfos)
307309#endif
308310 } //private static IEnumerable<FileInfo> ProcessSubDirs(DirectoryInfo srcDirInfo, string searchPattern, bool forHistory, int recursionLevel = 0)
309- private static void WriteException ( Exception ex )
311+ private static async Task WriteException ( Exception ex )
310312 {
311313 if ( ex is AggregateException aggex )
312314 {
313- WriteException ( aggex . InnerException ) ;
315+ await WriteException ( aggex . InnerException ) ;
314316 foreach ( var aggexInner in aggex . InnerExceptions )
315317 {
316- WriteException ( aggexInner ) ;
318+ await WriteException ( aggexInner ) ;
317319 }
318320 return ;
319321 }
320322
321- Console . WriteLine ( ex . Message ) ;
323+ //Console.WriteLine(ex.Message);
324+ StringBuilder message = new StringBuilder ( ex . Message ) ;
322325 while ( ex . InnerException != null )
323326 {
324327 ex = ex . InnerException ;
325- Console . WriteLine ( ex . Message ) ;
328+ //Console.WriteLine(ex.Message);
329+ message . Append ( Environment . NewLine + ex . Message ) ;
326330 }
331+
332+
333+ var time = DateTime . Now ;
334+ var msg = $ "[{ time : yyyy.MM.dd HH:mm:ss.ffff} ]:{ message } ";
335+ await AddMessage ( ConsoleColor . Red , msg , time , showAlert : true ) ;
336+ }
337+
338+ private static async Task AddMessage ( ConsoleColor color , string message , DateTime time , bool showAlert = false )
339+ {
340+ await Task . Run ( ( ) =>
341+ {
342+ lock ( ConsoleWatch . Lock )
343+ {
344+ try
345+ {
346+ Console . ForegroundColor = color ;
347+ Console . WriteLine ( message ) ;
348+
349+ if (
350+ showAlert
351+ && ( ConsoleWatch . PrevAlertTime != time || ConsoleWatch . PrevAlertMessage != message )
352+ )
353+ {
354+ MessageBox . Show ( message , "AsyncToSyncCodeRoundtripSynchroniserMonitor" ) ;
355+ }
356+ }
357+ catch ( Exception e )
358+ {
359+ Console . ForegroundColor = ConsoleColor . Red ;
360+ Console . WriteLine ( e . Message ) ;
361+ }
362+ finally
363+ {
364+ Console . ForegroundColor = ConsoleWatch . _consoleColor ;
365+ }
366+ }
367+ } ) ;
327368 }
328369
329- private static void WaitForCtrlC ( )
370+ private static Task WaitForCtrlC ( )
330371 {
331- var exitEvent = new ManualResetEvent ( false ) ;
372+ var exitEvent = new AsyncManualResetEvent ( false ) ;
332373 Console . CancelKeyPress += delegate ( object sender , ConsoleCancelEventArgs e )
333374 {
334375 e . Cancel = true ;
335376 Console . WriteLine ( "Stop detected." ) ;
336377 exitEvent . Set ( ) ;
337378 } ;
338- exitEvent . WaitOne ( ) ;
379+ return exitEvent . WaitAsync ( ) ;
339380 }
340381 }
341382
@@ -368,20 +409,23 @@ internal class ConsoleWatch
368409 /// <summary>
369410 /// The original console color
370411 /// </summary>
371- private static readonly ConsoleColor _consoleColor = Console . ForegroundColor ;
412+ internal static readonly ConsoleColor _consoleColor = Console . ForegroundColor ;
372413
373414 /// <summary>
374415 /// We need a static lock so it is shared by all.
375416 /// </summary>
376- private static readonly object Lock = new object ( ) ;
417+ internal static readonly object Lock = new object ( ) ;
377418 //private static readonly AsyncLock AsyncLock = new AsyncLock(); //TODO: use this
378419
420+ internal static DateTime PrevAlertTime ;
421+ internal static string PrevAlertMessage ;
422+
379423#pragma warning disable S2223 //Warning S2223 Change the visibility of 'DoingInitialSync' or make it 'const' or 'readonly'.
380424 public static bool DoingInitialSync = false ;
381425#pragma warning restore S2223
382426
383427 private static ConcurrentDictionary < string , DateTime > BidirectionalConverterSavedFileDates = new ConcurrentDictionary < string , DateTime > ( ) ;
384- private static readonly AsyncLockQueueDictionary FileEventLocks = new AsyncLockQueueDictionary ( ) ;
428+ private static readonly AsyncLockQueueDictionary < string > FileEventLocks = new AsyncLockQueueDictionary < string > ( ) ;
385429
386430
387431#pragma warning disable S1118 //Warning S1118 Hide this public constructor by making it 'protected'.
@@ -422,7 +466,9 @@ public static async Task WriteException(Exception ex, Context context)
422466 message . Append ( Environment . NewLine + ex . Message ) ;
423467 }
424468
425- await AddMessage ( ConsoleColor . Red , message . ToString ( ) , context ) ;
469+
470+ var msg = $ "[{ context . Time . ToLocalTime ( ) : yyyy.MM.dd HH:mm:ss.ffff} ] : { context . Event ? . FullName } : { message } ";
471+ await AddMessage ( ConsoleColor . Red , msg , context , showAlert : true ) ;
426472 }
427473
428474 public static bool IsSyncPath ( string fullNameInvariant )
@@ -836,7 +882,7 @@ private static async Task OnTouchedAsync(IFileSystemEvent fse, CancellationToken
836882 // }
837883 //}
838884
839- public static async Task AddMessage ( ConsoleColor color , string message , Context context )
885+ public static async Task AddMessage ( ConsoleColor color , string message , Context context , bool showAlert = false )
840886 {
841887 await Task . Run ( ( ) =>
842888 {
@@ -846,7 +892,18 @@ await Task.Run(() =>
846892 try
847893 {
848894 Console . ForegroundColor = color ;
849- Console . WriteLine ( $ "[{ context . Time . ToLocalTime ( ) : yyyy.MM.dd HH:mm:ss.ffff} ]:{ message } ") ;
895+ Console . WriteLine ( message ) ;
896+
897+ if (
898+ showAlert
899+ && ( PrevAlertTime != context . Time || PrevAlertMessage != message )
900+ )
901+ {
902+ PrevAlertTime = context . Time ;
903+ PrevAlertMessage = message ;
904+
905+ MessageBox . Show ( message , "AsyncToSyncCodeRoundtripSynchroniserMonitor" ) ;
906+ }
850907 }
851908 catch ( Exception e )
852909 {
0 commit comments