-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Please add an asynchronous Initialize function to the Application #17610
Comments
I think the async operations shouldn't be fone before the ui starts otherwise the user may get confused due to long loading times. |
Thanks for your reply. But I think adding a new async initialization might be a better solution. As for your suggestion that there shouldn't be a time-consuming effect when the program loads, I think this should be the choice of other developers, not the limitation of the framework itself. Taking a step back, a lot of the time, the internet connection is also very fast and doesn't affect the loading of the program. But since his connection is asynchronous, I should finish the asynchronous build when initializing. can be injected into the container, but it's clear that this isn't possible with the current synchronous approach. Actually, if it's in a desktop program, I can just use But in the web, this method will not be allowed to be used. So, I think it's essential for the current CSharp ecosystem to load programs, or other rewritable functions, and provide asynchronous related methods. Blazor, for example, provides a lot of synchronous and asynchronous APIs. Finally, I looked at the relevant source code and found that it was actually not very difficult to add asynchronous initialization. The most important thing is that it doesn't break the existing API. It's just a new addition. |
The problem with having What you can do is isolate you app into two parts: a very tiny part without DI and the real app with DI. The part without DI will be shown first and show a splash window (or view if mobile). This will show while loading and you will also construct your IoC container from this part. Once loaded, you then you navigate to your main app's view using the IoC just built and everything is the same as before. A third-party library could be made for this, but it might be too opinionated to include within Avalonia. There's likely a smart way to do this without an isolated splash screen, but your main window will have similar restrictions until DI kicks in to allow population/creation of child views. There's probably some work here to develop/teach better patterns. |
I see what you mean, but I still don't think it should be limited by frameworks. In short, if you support asynchronous methods, you won't have any problems performing synchronization, but if you call asynchronous methods in synchronous methods, unpredictable problems will occur. Please rethink the KISS principle. |
"Async void" is bad primarily for two reasons:
I am going to move second one out of the discussion quickly. In XAML frameworks task continuation goes to Dispatcher synchronization context by default. Which also means unhandled exceptions will go to Dispatcher thread and can be handled there. It won't crash any secondary threads but will go directly to the main thread. In case of app initialization, result is practically the same. The same goes to event handlers, which often are "async void" too.
While it's true, Avalonia initialization code cannot be fully asynchronous:
Meaning, we only can make |
This code has another issue though:
This code might cause issues with the fact that |
With Browser in general it's a special story. |
Can't you just rewrite this to use a factory method? EG public class WebSocketDmtpClientFactory {
private static IWebSocketDmtpClient Instance { get; set; }
public async Task<IWebSocketDmtpClient> GetClientAsync() {
if (Instance is not null} {
return instance;
}
var client = new WebSocketDmtpClient();
await client.SetupAsync(new TouchSocketConfig()
.SetDmtpOption(new DmtpOption { VerifyToken = "Dmtp" })
.ConfigurePlugins(a => a.UseDmtpRpc())
.SetRemoteIPHost("ws://localhost:5043/WebSocketDmtp"));
Instance = client;
return client
}
}
....
services.AddSingleton<WebSocketDmtpClientFactory>(); Obviously you still can't do async injection with this though. There is also a discussion here about adding real async support for MSDI: |
Thank you for your replies. I have a general understanding of the reasons why Initialize cannot be asynchronous and the current temporary solution. Thanks again |
Is your feature request related to a problem? Please describe.
The current Application class only has the Initialize synchronization function.
If I have some business that requires network communication and need to register communication components in the IOC container, then there will be problems.
Firstly, the connection of communication components is asynchronous, for example:
Task ConnectAsync()
And container registration must be synchronized, so I had to initialize the components in advance and register them as singleton.
For example:
But obviously, the use of
async void
here is very bad.Describe the solution you'd like
There is an asynchronous support Initialize method, for example:
Task InitializeAsync ()
Describe alternatives you've considered
I feel almost irreplaceable
Additional context
No response
The text was updated successfully, but these errors were encountered: