-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] async code and dispose in tests #14649
Conversation
@@ -48,7 +49,7 @@ public void UpdateNotificationWindowSize(int height) | |||
} | |||
} | |||
|
|||
public class NotificationCenterController | |||
public class NotificationCenterController : IDisposable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made this class disposable so we can clean up when the parent view extension is Disposed.
@@ -104,7 +102,7 @@ internal string SanitizeHtml(string content) | |||
|
|||
var output = GetData(processCommunicationTimeoutms); | |||
|
|||
return output.Result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This caused a deadlock when running tests on a single thread (could happen in live scenario too)
The .Result blocks the current thread until the task is completed.
And inside the GetData() the await Task will never finish because the main thread cannot poll for the status
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would an alternative be to always access this data from another thread, for example - like we do with the feature flags manager startup - run the GetData call inside on a task in the thread pool?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might work. But having a separate thread started everywhere GetData.Result is called might be harder to maintain
I find it easier to reason about when the entire concurrency logic is boxed up inside the GetData method so callers do not need to worry about how to call it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually used the approach you suggested for another case (in a test file)
https://github.com/DynamoDS/Dynamo/pull/14649/files#diff-be236d5cf3315a8f37d3d67a4adb628825430289b534dbd620952c47f2d286b0R1136
For production code (like GetData) I still think it would make it tricky to figure out how to use it safely.
Issues:
GetData().Result will block the current thread. Inside GetData we have an await which will cause the main thread to poll for the status of the awaited task
The calling thread cannot access this object because a different thread owns it
or something even weirder.UI tests were running on the threadpool sync context. This means that any async operation could be scheduled on the
threadpool. This can cause issues/exceptions with UI controls (like webview2)
Cannot access a disposed object
or something even weirder . UI tests can finish faster that async operations can execute. This means that a UI control could get disposed even if internal async operations have not finished yet