简体   繁体   中英

Async Tasks and Multi-threading in .Net Applications with SQL Server integration

Problem description : I am developing a .Net application with SQL Server interaction. That means the end user is able to create/update/delete entries on the SQL Server side from the application.

Recently, I was trying my application when I realized the UI stops for a couple seconds until the transactions between the application and the SQL Server finishes, then the UI begins to work again. Of course, this is not a good scenario for the end-user. So I started applying multi-threading to my application, but I realized I cannot provide access to the form until the saving process finishes.

For example: a form with one TextEdit control, the end user types his name in it and another TextEdit control, the end-user types his phone number in it then he hits the save button. The saving SQL from my application is

' Variable that holds the row number of the saved username
Dim SavedID as integer

' saving the username to the users table
SavedID = SQLControl.ExecScalar(String.format("INSERT INTO TABLE1 VALUES ({0});)", _
TextEdit1.text))

' saving the user phone number to the phone numbers table
SQLControl.ExecNonQuery(String.format("INSERT INTO TABLE2 VALUES ({0}, {1});)", _
SavedID, TextEdit2.text))

this means the end-user should not have access until the saving is finished because if he had access before the executing the second SQLNonQuery , the data might mess up.

PS: SQLControl.ExecScalar and SQLControl.ExecNonQuery are custom defined subroutines.

PS: I am already applying the parameters to my code but this code is only for describing my problem that I need to find a solution for.

Question : what is the best practice in dealing with such scenario if I need to apply the async tasks to save the data to SQL Server?

A few things:

  1. You're orchestrating between the UI and the database to the UI and then back to the database. At least from what's evident in your code, this is not needed and is resulting in unnecessary network latency, poor performance and does not handle failure scenarios at all. Try batching your calls to the database eg pass in TextEdit1.Text and TextEdit2.Text to a single stored procedure or database call and return back the SavedID if needed.

    1. You're not really following any patterns for layering or stratification. Look into the repository pattern and make sure you understand SRP (single responsibility principle). The UI is only meant for presentation logic, not for making database calls.

    2. As others have posted here, you are opening up your application to SQL injection attacks. This is a major security risk.

    3. You don't need multi-threading. You could benefit from async/TPL though. Look into the ADO.NET async library - ExecuteReaderAsync, ExecuteScalarAsync, ExecuteNonReaderAsync : https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.executereaderasync?view=netframework-4.7.2

    4. Async allows you to accomplish things in parallel using a single thread. This will make your UI responsive as background SQL tasks are completing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM