Merge pull request #323 from SolidAlloy/throw-exception-fix

Fix exceptions never being reported when UniTask is executed without await and Forget()
This commit is contained in:
Yoshifumi Kawai
2022-03-03 06:04:55 +09:00
committed by GitHub
2 changed files with 55 additions and 0 deletions

View File

@@ -194,6 +194,7 @@ namespace Cysharp.Threading.Tasks
sealed class ExceptionResultSource : IUniTaskSource
{
readonly ExceptionDispatchInfo exception;
bool calledGet;
public ExceptionResultSource(Exception exception)
{
@@ -202,6 +203,11 @@ namespace Cysharp.Threading.Tasks
public void GetResult(short token)
{
if (!calledGet)
{
calledGet = true;
GC.SuppressFinalize(this);
}
exception.Throw();
}
@@ -219,11 +225,20 @@ namespace Cysharp.Threading.Tasks
{
continuation(state);
}
~ExceptionResultSource()
{
if (!calledGet)
{
UniTaskScheduler.PublishUnobservedTaskException(exception.SourceException);
}
}
}
sealed class ExceptionResultSource<T> : IUniTaskSource<T>
{
readonly ExceptionDispatchInfo exception;
bool calledGet;
public ExceptionResultSource(Exception exception)
{
@@ -232,12 +247,22 @@ namespace Cysharp.Threading.Tasks
public T GetResult(short token)
{
if (!calledGet)
{
calledGet = true;
GC.SuppressFinalize(this);
}
exception.Throw();
return default;
}
void IUniTaskSource.GetResult(short token)
{
if (!calledGet)
{
calledGet = true;
GC.SuppressFinalize(this);
}
exception.Throw();
}
@@ -255,6 +280,14 @@ namespace Cysharp.Threading.Tasks
{
continuation(state);
}
~ExceptionResultSource()
{
if (!calledGet)
{
UniTaskScheduler.PublishUnobservedTaskException(exception.SourceException);
}
}
}
sealed class CanceledResultSource : IUniTaskSource

View File

@@ -366,6 +366,28 @@ namespace Cysharp.Threading.TasksTests
UniTaskScheduler.UnobservedTaskException -= action;
});
[UnityTest]
public IEnumerator ThrowExceptionUnawaited() => UniTask.ToCoroutine(async () =>
{
LogAssert.Expect(LogType.Exception, "Exception: MyException");
#pragma warning disable 1998
async UniTask Throw() => throw new Exception("MyException");
#pragma warning restore 1998
#pragma warning disable 4014
Throw();
#pragma warning restore 4014
await UniTask.DelayFrame(3);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await UniTask.DelayFrame(1);
});
async UniTask InException1()
{
await UniTask.Yield();