-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Closed
Labels
area-System.IOhelp wanted[up-for-grabs] Good issue for external contributors[up-for-grabs] Good issue for external contributors
Milestone
Description
Description
When a unhandled exception is raised in event handler of FileSystemWatcher (what is local member of a task) the exception terminates the task (and application) when running under windows. Under Linux the application is not terminated.
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ThreadException
{
class Program
{
static async Task Main(string[] args)
{
// Generate test file
var filePath = GetAbsolutePath("Data/test.json");
Directory.CreateDirectory(GetAbsolutePath("Data"));
await File.WriteAllTextAsync(filePath, "[]", Encoding.UTF8);
var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, args) => {
cts.Cancel();
};
// Start the tasks, that do the work
await RunMainProgramAsync(cts.Token);
System.Console.WriteLine("Program Finished!");
}
private static async Task RunMainProgramAsync(CancellationToken token)
{
try
{
await Task.Run(async () => {
using var observer = new FSObserver();
while(!token.IsCancellationRequested)
{
observer.DoSomething();
await Task.Delay(250);
}
}, token);
}
catch(Exception e)
{
System.Console.Error.WriteLine(e.Message);
}
}
public static string GetAbsolutePath(string relativePath)
{
var _dataRoot = new FileInfo(typeof(Program).Assembly.Location);
string assemblyFolderPath = _dataRoot.Directory.FullName;
string fullPath = Path.Combine(assemblyFolderPath, relativePath);
return fullPath;
}
}
class FSObserver : IDisposable
{
private FileSystemWatcher _fs;
private string _filePath;
public FSObserver()
{
_filePath = Program.GetAbsolutePath("Data");
_fs = new FileSystemWatcher();
_fs.Path = _filePath;
_fs.Filter = "test.json";
_fs.EnableRaisingEvents = true;
_fs.Changed += (sender, args) => {
System.Console.WriteLine($"file {args.FullPath} was changed: {args.ChangeType}");
ReloadModel();
};
}
public void DoSomething()
{
System.Console.WriteLine("write something");
}
public void Dispose()
{
_fs?.Dispose();
}
private void ReloadModel()
{
// Simulate an error while parsing model
throw new Exception("ohh no :-/");
}
}
}Test steps:
- run the program
- open shell in folder with executables
- update the file
echo "" > test.jsonBehavior under windows:
Application is terminated.
Behavior under linux:
Application is still running, file system watch don't fire events on further changes to file. It seems that the tasks, that hosted the filesystem watcher is still running.
Expectation:
The behavior under both OS should be the same, from my point of view unhandled exception should crash the application.
Configuration
Tested with:
- netcoreapp3.1 (3.1.405)
- net5.0 (5.0.102)
Operating systems
- Win10 (20H2)
- Ubuntu 18.04
- Ubuntu 20.04
Architecture:
- x64
Regression?
n/a
Other information
Console output (Windows):
write something
file C:\ThreadException\bin\Debug\net5.0\Data\test.json was changed: Changed
Exception thrown: 'System.Exception' in ThreadException.dll
write something
Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.2\System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.2\System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.2\System.Collections.Immutable.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.2\System.Runtime.InteropServices.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
write something
Unhandled exception. System.Exception: ohh no :-/
at ThreadException.FSObserver.ReloadModel() in C:\Users\alkopke\repo\hackathon\ThreadException\Program.cs:line 88
at ThreadException.FSObserver.<.ctor>b__2_0(Object sender, FileSystemEventArgs args) in C:\Users\alkopke\repo\hackathon\ThreadException\Program.cs:line 71
at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(WatcherChangeTypes changeType, ReadOnlySpan`1 name)
at System.IO.FileSystemWatcher.ParseEventBufferAndNotifyForEach(Byte[] buffer, UInt32 numBytes)
at System.IO.FileSystemWatcher.ReadDirectoryChangesCallback(UInt32 errorCode, UInt32 numBytes, AsyncReadState state)
at System.IO.FileSystemWatcher.<>c.<StartRaisingEvents>b__83_0(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
at System.Threading.ThreadPoolBoundHandleOverlapped.CompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pNativeOverlapped)
The program '[34932] ThreadException.dll' has exited with code 0 (0x0).Console output (Linux):
write something
file /home/sandboxuser/ThreadException/bin/Debug/net5.0/Data/test.json was changed: Changed
Exception thrown: 'System.Exception' in ThreadException.dll
write something
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/5.0.2/System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/5.0.2/System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/5.0.2/System.Collections.Immutable.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
write somethingReactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area-System.IOhelp wanted[up-for-grabs] Good issue for external contributors[up-for-grabs] Good issue for external contributors