TestDispatcher
TDishop opened this issue · 4 comments
Is there a way to control AsyncContextThread thread creation and also keep context/thread available for more than one set of tasks? For some integration test projects, I would like to create a TestDispatcher during test assembly initialization and use it to initially create many objects and then dispatch back to thread just like Assembly.Current.Dispatcher.Invoke would do. I didn't see any example like this. Seems like all examples just execute a limited set of operations on a context.
Also, what is recommended approach for using in .netframework projects (.net48) since latest version is only .netstandard1.3 and 2.0 Should this be asked in a different issue?
And there have been no updates recently. Is this because .netcore5 will supported more of this behavior out of the box?
Is there a way to control AsyncContextThread thread creation and also keep context/thread available for more than one set of tasks?
Yes. This is considered an advanced usage, so some of the members are hidden from IntelliSense by default. You can create a new AsyncContextThread
, and that instance will already be running its main loop. You can then queue tasks to it by using AsyncContextThread.Context.Factory
, and when you're done with it you can call AsyncContextThread.JoinAsync
to asynchronously wait for all continuations to complete.
For some integration test projects, I would like to create a TestDispatcher during test assembly initialization and use it to initially create many objects and then dispatch back to thread just like Assembly.Current.Dispatcher.Invoke would do.
AsyncContextThread
provides a single-threaded context, but it does not provide an actual Win32 message pumping windows procedure loop. If your code under test is using Invoke
and friends to update in-memory data structures (e.g., ViewModels that are not bound to actual UI components), then that would work fine. But if they're using Invoke
to actually update UI components, then you would need to use a real Dispatcher
instance like this (unsupported) code does.
Also, what is recommended approach for using in .netframework projects (.net48) since latest version is only .netstandard1.3 and 2.0?
net48
supports netstandard2.0
, so it works fine with a normal NuGet install.
And there have been no updates recently. Is this because .netcore5 will supported more of this behavior out of the box?
No; .NET Core doesn't include much AsyncEx behavior. .NET has added a little bit over the years (and I remove it from AsyncEx when that happens). This library is mostly "done"; there's not many features planned. Better support for ValueTasks would be nice, as well as a few other optimizations, but overall there's not been a need to change this library recently.
This is how I am calling:
_asyncThread = new AsyncContextThread();
_asyncContext = _asyncThread.Context;
_synchContext = _asyncContext.SynchronizationContext;
// call non async action on thread
synchContext.Send( => { act(); }, null);
// call non async function on thread
return _synchContext.Send(() => { return myFunc(); });
// call asyn action
return _synchContext.PostAsync(() => { return act(); });
// call async function
return _synchContext.PostAsync(() => { return asyncFunc(); });
Are those correct or should I be using something simpler?
The only thing I can't do is control how the thread is created. I don't think I need the a windows procedure loop or pump messages but I would like to be able to set a control property so I don't have to add conditionals. That requires STA. Probably would be better to refactor out so that is not needed, but not sure how easy with some third party controls/libraries.
Don't see anyway to force STA from outside Nito.AsyncEx
I don't think I need the a windows procedure loop or pump messages... That requires STA.
An STA thread requires a message pump. It you do need an STA thread, then AsyncContextThread
will not work for you. I'm not aware of any library that would provide this functionality, so I would recommend using WpfContext
.