A set of .NET Framework managed libraries for developing graphical user interfaces.
Hi,
Thanks for kind answer.
BTW, what do I do for DisplayData()?
How to sync ReadData() and DisplayData()?
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
From the main form, the SettingForm is loaded by clicking a toolbar button.
In the SettingForm_load event, the setting data is read by calling the function(ReadData) which read data from database.
After that, display the setting data(DisplayData) on the TabControl.
Problem is that it takes 1~2 seconds to complete the ReadData, this blocks displaying the SettingForm.
I want to display SettingForm first and then have data is displayed.
I want to do this by asynchronous programming using Task class.
How to do this?
A set of .NET Framework managed libraries for developing graphical user interfaces.
Hi,
Thanks for kind answer.
BTW, what do I do for DisplayData()?
How to sync ReadData() and DisplayData()?
Hello @JeffinAtl
Not knowing specifics like how data should be returned and if this is conventional read or with Entity Framework core the following should still provide the basics.
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace SqlServerAsyncRead.Classes
{
public class DataOperations
{
private static string _connectionString =
"Data Source=.\\sqlexpress;Initial Catalog=NorthWind2020;Integrated Security=True";
public static async Task<DataTable> ReadProductsTask()
{
return await Task.Run(async () =>
{
var productTable = new DataTable();
using (var cn = new SqlConnection(_connectionString))
{
using (var cmd = new SqlCommand() { Connection = cn })
{
cmd.CommandText = SelectStatement();
await cn.OpenAsync();
productTable.Load(await cmd.ExecuteReaderAsync());
}
}
return productTable;
});
}
private static string SelectStatement()
{
return "SELECT P.ProductID, P.ProductName, P.SupplierID, S.CompanyName, P.CategoryID, " +
"C.CategoryName, P.QuantityPerUnit, P.UnitPrice, P.UnitsInStock, P.UnitsOnOrder, " +
"P.ReorderLevel, P.Discontinued, P.DiscontinuedDate " +
"FROM Products AS P INNER JOIN Categories AS C ON P.CategoryID = C.CategoryID " +
"INNER JOIN Suppliers AS S ON P.SupplierID = S.SupplierID";
}
}
}
Calling the above to a DataGridView (which could be other controls too)
private async void Form1_Load(object sender, EventArgs e)
{
var table = await DataOperations.ReadProductsTask();
dataGridView1.DataSource = table;
}
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using NorthEntityLibrary.Contexts;
namespace NorthEntityLibrary.Classes
{
public class ProductOperations
{
public static NorthwindContext Context { get; } = new NorthwindContext();
public static async Task<List<Product>> GetProducts()
{
var productList = new List<Product>();
await Task.Run(async () =>
{
productList = await Context.Products
.Include(product => product.Supplier)
.Include(product => product.Category)
.Select(Product.Projection)
.ToListAsync();
});
return productList;
}
}
}
using System;
using System.Linq.Expressions;
using NorthClassLibrary.Models;
using NorthEntityLibrary.Models;
namespace NorthEntityLibrary.Classes
{
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public int? SupplierId { get; set; }
public string SupplierName { get; set; }
public string QuantityPerUnit { get; set; }
public decimal? UnitPrice { get; set; }
public short? UnitsInStock { get; set; }
public short? UnitsOnOrder { get; set; }
public short? ReorderLevel { get; set; }
public override string ToString() => ProductName;
public static Expression<Func<Products, Product>> Projection =>
product => new Product()
{
ProductId = product.ProductID,
ProductName = product.ProductName,
SupplierName = product.Supplier.CompanyName,
SupplierId = product.SupplierID,
QuantityPerUnit = product.QuantityPerUnit,
ReorderLevel = product.ReorderLevel,
UnitPrice = product.UnitPrice,
UnitsInStock = product.UnitsInStock,
UnitsOnOrder = product.UnitsOnOrder
};
}
}
var products = await ProductOperations.GetProducts();
There are times when it's possible to run into cross threading violations which this following extension is good for.
public static class ControlExtensions
{
public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : ISynchronizeInvoke
{
if (control.InvokeRequired)
{
control.Invoke(new Action(() => action(control)), null);
}
else
{
action(control);
}
}
}
dataGridView1.InvokeIfRequired(dgv =>
{
dgv.DataSource = await DataOperations.ReadProductsTask();
});