Aysnc method still blocking the ui interface
I have this method which is using ODBC and executes the reader async but the method is still blocking my UI for some reason it's loading 4000 records but I am wondering if someone can look at my code see where I am going wrong.
async Task<BindingList<PurchaseLinkHeaderC>> GetPurchaseOrders( IProgress<int> progress)
{
BindingList<PurchaseLinkHeaderC> _purhcaseOrderList = new BindingList<PurchaseLinkHeaderC>();
try
{
string sageDsn = ConfigurationManager.AppSettings["SageDSN"];
string sageUsername = ConfigurationManager.AppSettings["SageUsername"];
string sagePassword = ConfigurationManager.AppSettings["SagePassword"];
//using (var connection = new OdbcConnection("DSN=SageLine50v24;Uid=Manager;Pwd=;"))
using (var connection =
new OdbcConnection(String.Format("DSN={0};Uid={1};Pwd={2};", sageDsn, sageUsername, sagePassword)))
{
connection.Open();
string fromD = dtpFrom.Value.ToString("yyyy-MM-dd");
string toD = dtpTo.Value.ToString("yyyy-MM-dd");
string SQL =
"SELECT 'ORDER_NUMBER', 'ORDER_OR_QUOTE', 'ORDER_DATE', 'DELIVERY_DATE', 'ORDER_STATUS_CODE', 'ORDER_STATUS', 'DELIVERY_STATUS_CODE', 'DELIVERY_STATUS', 'ACCOUNT_REF', 'NAME', 'ADDRESS_1', 'ADDRESS_2', 'ADDRESS_3', 'ADDRESS_4', 'ADDRESS_5', 'C_ADDRESS_1', 'C_ADDRESS_2', 'C_ADDRESS_3', 'C_ADDRESS_4', 'C_ADDRESS_5', 'DEL_NAME', 'DEL_ADDRESS_1', 'DEL_ADDRESS_2', 'DEL_ADDRESS_3', 'DEL_ADDRESS_4', 'DEL_ADDRESS_5', 'VAT_REG_NUMBER', 'REFERENCE', 'CONTACT_NAME', 'TAKEN_BY', 'SUPP_ORDER_NUMBER', 'SUPP_TEL_NUMBER', 'NOTES_1', 'NOTES_2', 'NOTES_3', 'SUPP_DISC_RATE', 'FOREIGN_ITEMS_NET', 'FOREIGN_ITEMS_TAX', 'FOREIGN_ITEMS_GROSS', 'ITEMS_NET', 'ITEMS_TAX', 'ITEMS_GROSS', 'TAX_RATE_1', 'TAX_RATE_2', 'TAX_RATE_3', 'TAX_RATE_4', 'TAX_RATE_5', 'NET_AMOUNT_1', 'NET_AMOUNT_2', 'NET_AMOUNT_3', 'NET_AMOUNT_4', 'NET_AMOUNT_5', 'TAX_AMOUNT_1', 'TAX_AMOUNT_2', 'TAX_AMOUNT_3', 'TAX_AMOUNT_4', 'TAX_AMOUNT_5', 'COURIER_NUMBER', 'COURIER_NAME', 'CONSIGNMENT', 'CARR_NOM_CODE', 'CARR_TAX_CODE', 'CARR_DEPT_NUMBER', 'CARR_DEPT_NAME', 'FOREIGN_CARR_NET', 'FOREIGN_CARR_TAX', 'FOREIGN_CARR_GROSS', 'CARR_NET', 'CARR_TAX', 'CARR_GROSS', 'FOREIGN_INVOICE_NET', 'FOREIGN_INVOICE_TAX', 'FOREIGN_INVOICE_GROSS', 'INVOICE_NET', 'INVOICE_TAX', 'INVOICE_GROSS', 'CURRENCY', 'CURRENCY_TYPE', 'EURO_GROSS', 'EURO_RATE', 'FOREIGN_RATE', 'SETTLEMENT_DUE_DAYS', 'SETTLEMENT_DISC_RATE', 'FOREIGN_SETTLEMENT_DISC_AMOUNT', 'FOREIGN_SETTLEMENT_TOTAL', 'SETTLEMENT_DISC_AMOUNT', 'SETTLEMENT_TOTAL', 'PAYMENT_REF', 'PRINTED', 'PRINTED_CODE', 'POSTED', 'POSTED_CODE', 'QUOTE_STATUS_ID', 'RECURRING_REF', 'DUNS_NUMBER', 'PAYMENT_TYPE', 'BANK_REF', 'GDN_NUMBER', 'PROJECT_ID', 'ANALYSIS_1', 'ANALYSIS_2', 'ANALYSIS_3', 'INVOICE_PAYMENT_ID', 'RESUBMIT_INVOICE_PAYMENT_REQUIRED', 'RECORD_CREATE_DATE', 'RECORD_MODIFY_DATE', 'RECORD_DELETED' FROM 'PURCHASE_ORDER' WHERE ORDER_DATE >='{0}' and ORDER_DATE <='{1}'";
int counter = 0;
using (var command = new OdbcCommand(string.Format(SQL, fromD, toD), connection))
{
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
var purhcaseOrders = new PurchaseLinkHeaderC();
if ((reader["ORDER_NUMBER"] != ""))
{
counter++;
string orderNumber = Convert.ToString(reader["ORDER_NUMBER"]);
purhcaseOrders.Order_Number = OrderNumber.ToString();
purhcaseOrders.PurchaseOrderNo = Convert.ToInt32(reader["ORDER_NUMBER"]);
purhcaseOrders.Name = reader["NAME"].ToString();
purhcaseOrders.Selected_PurchaseOrder = false;
_purhcaseOrderList.Add(purhcaseOrders);
}
}
}
}
}
}
catch (Exception ex)
{
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info(ex, "Error at GetSalesOrders " + ex.ToString());
}
return _purhcaseOrderList;
}
I want to be able to show a progress bar of the list being loaded so I was attempting to call it as this way. But I am not sure how to attach the progress method either.
var progressIndicator = new Progress<int>(ReportProgress);
//call async method
BindingList<PurchaseLinkHeaderC> purchaseOrders = await GetPurchaseOrders(progressIndicator);
_masterPurchaseOrders = purchaseOrders;
I am hoping that someone can help here.
c# winforms async-await
add a comment |
I have this method which is using ODBC and executes the reader async but the method is still blocking my UI for some reason it's loading 4000 records but I am wondering if someone can look at my code see where I am going wrong.
async Task<BindingList<PurchaseLinkHeaderC>> GetPurchaseOrders( IProgress<int> progress)
{
BindingList<PurchaseLinkHeaderC> _purhcaseOrderList = new BindingList<PurchaseLinkHeaderC>();
try
{
string sageDsn = ConfigurationManager.AppSettings["SageDSN"];
string sageUsername = ConfigurationManager.AppSettings["SageUsername"];
string sagePassword = ConfigurationManager.AppSettings["SagePassword"];
//using (var connection = new OdbcConnection("DSN=SageLine50v24;Uid=Manager;Pwd=;"))
using (var connection =
new OdbcConnection(String.Format("DSN={0};Uid={1};Pwd={2};", sageDsn, sageUsername, sagePassword)))
{
connection.Open();
string fromD = dtpFrom.Value.ToString("yyyy-MM-dd");
string toD = dtpTo.Value.ToString("yyyy-MM-dd");
string SQL =
"SELECT 'ORDER_NUMBER', 'ORDER_OR_QUOTE', 'ORDER_DATE', 'DELIVERY_DATE', 'ORDER_STATUS_CODE', 'ORDER_STATUS', 'DELIVERY_STATUS_CODE', 'DELIVERY_STATUS', 'ACCOUNT_REF', 'NAME', 'ADDRESS_1', 'ADDRESS_2', 'ADDRESS_3', 'ADDRESS_4', 'ADDRESS_5', 'C_ADDRESS_1', 'C_ADDRESS_2', 'C_ADDRESS_3', 'C_ADDRESS_4', 'C_ADDRESS_5', 'DEL_NAME', 'DEL_ADDRESS_1', 'DEL_ADDRESS_2', 'DEL_ADDRESS_3', 'DEL_ADDRESS_4', 'DEL_ADDRESS_5', 'VAT_REG_NUMBER', 'REFERENCE', 'CONTACT_NAME', 'TAKEN_BY', 'SUPP_ORDER_NUMBER', 'SUPP_TEL_NUMBER', 'NOTES_1', 'NOTES_2', 'NOTES_3', 'SUPP_DISC_RATE', 'FOREIGN_ITEMS_NET', 'FOREIGN_ITEMS_TAX', 'FOREIGN_ITEMS_GROSS', 'ITEMS_NET', 'ITEMS_TAX', 'ITEMS_GROSS', 'TAX_RATE_1', 'TAX_RATE_2', 'TAX_RATE_3', 'TAX_RATE_4', 'TAX_RATE_5', 'NET_AMOUNT_1', 'NET_AMOUNT_2', 'NET_AMOUNT_3', 'NET_AMOUNT_4', 'NET_AMOUNT_5', 'TAX_AMOUNT_1', 'TAX_AMOUNT_2', 'TAX_AMOUNT_3', 'TAX_AMOUNT_4', 'TAX_AMOUNT_5', 'COURIER_NUMBER', 'COURIER_NAME', 'CONSIGNMENT', 'CARR_NOM_CODE', 'CARR_TAX_CODE', 'CARR_DEPT_NUMBER', 'CARR_DEPT_NAME', 'FOREIGN_CARR_NET', 'FOREIGN_CARR_TAX', 'FOREIGN_CARR_GROSS', 'CARR_NET', 'CARR_TAX', 'CARR_GROSS', 'FOREIGN_INVOICE_NET', 'FOREIGN_INVOICE_TAX', 'FOREIGN_INVOICE_GROSS', 'INVOICE_NET', 'INVOICE_TAX', 'INVOICE_GROSS', 'CURRENCY', 'CURRENCY_TYPE', 'EURO_GROSS', 'EURO_RATE', 'FOREIGN_RATE', 'SETTLEMENT_DUE_DAYS', 'SETTLEMENT_DISC_RATE', 'FOREIGN_SETTLEMENT_DISC_AMOUNT', 'FOREIGN_SETTLEMENT_TOTAL', 'SETTLEMENT_DISC_AMOUNT', 'SETTLEMENT_TOTAL', 'PAYMENT_REF', 'PRINTED', 'PRINTED_CODE', 'POSTED', 'POSTED_CODE', 'QUOTE_STATUS_ID', 'RECURRING_REF', 'DUNS_NUMBER', 'PAYMENT_TYPE', 'BANK_REF', 'GDN_NUMBER', 'PROJECT_ID', 'ANALYSIS_1', 'ANALYSIS_2', 'ANALYSIS_3', 'INVOICE_PAYMENT_ID', 'RESUBMIT_INVOICE_PAYMENT_REQUIRED', 'RECORD_CREATE_DATE', 'RECORD_MODIFY_DATE', 'RECORD_DELETED' FROM 'PURCHASE_ORDER' WHERE ORDER_DATE >='{0}' and ORDER_DATE <='{1}'";
int counter = 0;
using (var command = new OdbcCommand(string.Format(SQL, fromD, toD), connection))
{
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
var purhcaseOrders = new PurchaseLinkHeaderC();
if ((reader["ORDER_NUMBER"] != ""))
{
counter++;
string orderNumber = Convert.ToString(reader["ORDER_NUMBER"]);
purhcaseOrders.Order_Number = OrderNumber.ToString();
purhcaseOrders.PurchaseOrderNo = Convert.ToInt32(reader["ORDER_NUMBER"]);
purhcaseOrders.Name = reader["NAME"].ToString();
purhcaseOrders.Selected_PurchaseOrder = false;
_purhcaseOrderList.Add(purhcaseOrders);
}
}
}
}
}
}
catch (Exception ex)
{
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info(ex, "Error at GetSalesOrders " + ex.ToString());
}
return _purhcaseOrderList;
}
I want to be able to show a progress bar of the list being loaded so I was attempting to call it as this way. But I am not sure how to attach the progress method either.
var progressIndicator = new Progress<int>(ReportProgress);
//call async method
BindingList<PurchaseLinkHeaderC> purchaseOrders = await GetPurchaseOrders(progressIndicator);
_masterPurchaseOrders = purchaseOrders;
I am hoping that someone can help here.
c# winforms async-await
What are you doing inGetPurchaseOrders()
method actually?
– Rahul
Nov 20 '18 at 9:25
@Rahul the GetPurchaseOrders is shown in its enterity above its going to odbc in sage to retrieve orders from the tables using odbc sql
– david
Nov 20 '18 at 9:31
You are not reporting any progress through yourIProgress<int>
. You should also see stackoverflow.com/q/332365/11683 for why you must not usestring.Format
to build a query.
– GSerg
Nov 20 '18 at 9:39
@GSerg that is the secondary issue main issue is the blocking of the ui
– david
Nov 20 '18 at 9:43
add a comment |
I have this method which is using ODBC and executes the reader async but the method is still blocking my UI for some reason it's loading 4000 records but I am wondering if someone can look at my code see where I am going wrong.
async Task<BindingList<PurchaseLinkHeaderC>> GetPurchaseOrders( IProgress<int> progress)
{
BindingList<PurchaseLinkHeaderC> _purhcaseOrderList = new BindingList<PurchaseLinkHeaderC>();
try
{
string sageDsn = ConfigurationManager.AppSettings["SageDSN"];
string sageUsername = ConfigurationManager.AppSettings["SageUsername"];
string sagePassword = ConfigurationManager.AppSettings["SagePassword"];
//using (var connection = new OdbcConnection("DSN=SageLine50v24;Uid=Manager;Pwd=;"))
using (var connection =
new OdbcConnection(String.Format("DSN={0};Uid={1};Pwd={2};", sageDsn, sageUsername, sagePassword)))
{
connection.Open();
string fromD = dtpFrom.Value.ToString("yyyy-MM-dd");
string toD = dtpTo.Value.ToString("yyyy-MM-dd");
string SQL =
"SELECT 'ORDER_NUMBER', 'ORDER_OR_QUOTE', 'ORDER_DATE', 'DELIVERY_DATE', 'ORDER_STATUS_CODE', 'ORDER_STATUS', 'DELIVERY_STATUS_CODE', 'DELIVERY_STATUS', 'ACCOUNT_REF', 'NAME', 'ADDRESS_1', 'ADDRESS_2', 'ADDRESS_3', 'ADDRESS_4', 'ADDRESS_5', 'C_ADDRESS_1', 'C_ADDRESS_2', 'C_ADDRESS_3', 'C_ADDRESS_4', 'C_ADDRESS_5', 'DEL_NAME', 'DEL_ADDRESS_1', 'DEL_ADDRESS_2', 'DEL_ADDRESS_3', 'DEL_ADDRESS_4', 'DEL_ADDRESS_5', 'VAT_REG_NUMBER', 'REFERENCE', 'CONTACT_NAME', 'TAKEN_BY', 'SUPP_ORDER_NUMBER', 'SUPP_TEL_NUMBER', 'NOTES_1', 'NOTES_2', 'NOTES_3', 'SUPP_DISC_RATE', 'FOREIGN_ITEMS_NET', 'FOREIGN_ITEMS_TAX', 'FOREIGN_ITEMS_GROSS', 'ITEMS_NET', 'ITEMS_TAX', 'ITEMS_GROSS', 'TAX_RATE_1', 'TAX_RATE_2', 'TAX_RATE_3', 'TAX_RATE_4', 'TAX_RATE_5', 'NET_AMOUNT_1', 'NET_AMOUNT_2', 'NET_AMOUNT_3', 'NET_AMOUNT_4', 'NET_AMOUNT_5', 'TAX_AMOUNT_1', 'TAX_AMOUNT_2', 'TAX_AMOUNT_3', 'TAX_AMOUNT_4', 'TAX_AMOUNT_5', 'COURIER_NUMBER', 'COURIER_NAME', 'CONSIGNMENT', 'CARR_NOM_CODE', 'CARR_TAX_CODE', 'CARR_DEPT_NUMBER', 'CARR_DEPT_NAME', 'FOREIGN_CARR_NET', 'FOREIGN_CARR_TAX', 'FOREIGN_CARR_GROSS', 'CARR_NET', 'CARR_TAX', 'CARR_GROSS', 'FOREIGN_INVOICE_NET', 'FOREIGN_INVOICE_TAX', 'FOREIGN_INVOICE_GROSS', 'INVOICE_NET', 'INVOICE_TAX', 'INVOICE_GROSS', 'CURRENCY', 'CURRENCY_TYPE', 'EURO_GROSS', 'EURO_RATE', 'FOREIGN_RATE', 'SETTLEMENT_DUE_DAYS', 'SETTLEMENT_DISC_RATE', 'FOREIGN_SETTLEMENT_DISC_AMOUNT', 'FOREIGN_SETTLEMENT_TOTAL', 'SETTLEMENT_DISC_AMOUNT', 'SETTLEMENT_TOTAL', 'PAYMENT_REF', 'PRINTED', 'PRINTED_CODE', 'POSTED', 'POSTED_CODE', 'QUOTE_STATUS_ID', 'RECURRING_REF', 'DUNS_NUMBER', 'PAYMENT_TYPE', 'BANK_REF', 'GDN_NUMBER', 'PROJECT_ID', 'ANALYSIS_1', 'ANALYSIS_2', 'ANALYSIS_3', 'INVOICE_PAYMENT_ID', 'RESUBMIT_INVOICE_PAYMENT_REQUIRED', 'RECORD_CREATE_DATE', 'RECORD_MODIFY_DATE', 'RECORD_DELETED' FROM 'PURCHASE_ORDER' WHERE ORDER_DATE >='{0}' and ORDER_DATE <='{1}'";
int counter = 0;
using (var command = new OdbcCommand(string.Format(SQL, fromD, toD), connection))
{
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
var purhcaseOrders = new PurchaseLinkHeaderC();
if ((reader["ORDER_NUMBER"] != ""))
{
counter++;
string orderNumber = Convert.ToString(reader["ORDER_NUMBER"]);
purhcaseOrders.Order_Number = OrderNumber.ToString();
purhcaseOrders.PurchaseOrderNo = Convert.ToInt32(reader["ORDER_NUMBER"]);
purhcaseOrders.Name = reader["NAME"].ToString();
purhcaseOrders.Selected_PurchaseOrder = false;
_purhcaseOrderList.Add(purhcaseOrders);
}
}
}
}
}
}
catch (Exception ex)
{
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info(ex, "Error at GetSalesOrders " + ex.ToString());
}
return _purhcaseOrderList;
}
I want to be able to show a progress bar of the list being loaded so I was attempting to call it as this way. But I am not sure how to attach the progress method either.
var progressIndicator = new Progress<int>(ReportProgress);
//call async method
BindingList<PurchaseLinkHeaderC> purchaseOrders = await GetPurchaseOrders(progressIndicator);
_masterPurchaseOrders = purchaseOrders;
I am hoping that someone can help here.
c# winforms async-await
I have this method which is using ODBC and executes the reader async but the method is still blocking my UI for some reason it's loading 4000 records but I am wondering if someone can look at my code see where I am going wrong.
async Task<BindingList<PurchaseLinkHeaderC>> GetPurchaseOrders( IProgress<int> progress)
{
BindingList<PurchaseLinkHeaderC> _purhcaseOrderList = new BindingList<PurchaseLinkHeaderC>();
try
{
string sageDsn = ConfigurationManager.AppSettings["SageDSN"];
string sageUsername = ConfigurationManager.AppSettings["SageUsername"];
string sagePassword = ConfigurationManager.AppSettings["SagePassword"];
//using (var connection = new OdbcConnection("DSN=SageLine50v24;Uid=Manager;Pwd=;"))
using (var connection =
new OdbcConnection(String.Format("DSN={0};Uid={1};Pwd={2};", sageDsn, sageUsername, sagePassword)))
{
connection.Open();
string fromD = dtpFrom.Value.ToString("yyyy-MM-dd");
string toD = dtpTo.Value.ToString("yyyy-MM-dd");
string SQL =
"SELECT 'ORDER_NUMBER', 'ORDER_OR_QUOTE', 'ORDER_DATE', 'DELIVERY_DATE', 'ORDER_STATUS_CODE', 'ORDER_STATUS', 'DELIVERY_STATUS_CODE', 'DELIVERY_STATUS', 'ACCOUNT_REF', 'NAME', 'ADDRESS_1', 'ADDRESS_2', 'ADDRESS_3', 'ADDRESS_4', 'ADDRESS_5', 'C_ADDRESS_1', 'C_ADDRESS_2', 'C_ADDRESS_3', 'C_ADDRESS_4', 'C_ADDRESS_5', 'DEL_NAME', 'DEL_ADDRESS_1', 'DEL_ADDRESS_2', 'DEL_ADDRESS_3', 'DEL_ADDRESS_4', 'DEL_ADDRESS_5', 'VAT_REG_NUMBER', 'REFERENCE', 'CONTACT_NAME', 'TAKEN_BY', 'SUPP_ORDER_NUMBER', 'SUPP_TEL_NUMBER', 'NOTES_1', 'NOTES_2', 'NOTES_3', 'SUPP_DISC_RATE', 'FOREIGN_ITEMS_NET', 'FOREIGN_ITEMS_TAX', 'FOREIGN_ITEMS_GROSS', 'ITEMS_NET', 'ITEMS_TAX', 'ITEMS_GROSS', 'TAX_RATE_1', 'TAX_RATE_2', 'TAX_RATE_3', 'TAX_RATE_4', 'TAX_RATE_5', 'NET_AMOUNT_1', 'NET_AMOUNT_2', 'NET_AMOUNT_3', 'NET_AMOUNT_4', 'NET_AMOUNT_5', 'TAX_AMOUNT_1', 'TAX_AMOUNT_2', 'TAX_AMOUNT_3', 'TAX_AMOUNT_4', 'TAX_AMOUNT_5', 'COURIER_NUMBER', 'COURIER_NAME', 'CONSIGNMENT', 'CARR_NOM_CODE', 'CARR_TAX_CODE', 'CARR_DEPT_NUMBER', 'CARR_DEPT_NAME', 'FOREIGN_CARR_NET', 'FOREIGN_CARR_TAX', 'FOREIGN_CARR_GROSS', 'CARR_NET', 'CARR_TAX', 'CARR_GROSS', 'FOREIGN_INVOICE_NET', 'FOREIGN_INVOICE_TAX', 'FOREIGN_INVOICE_GROSS', 'INVOICE_NET', 'INVOICE_TAX', 'INVOICE_GROSS', 'CURRENCY', 'CURRENCY_TYPE', 'EURO_GROSS', 'EURO_RATE', 'FOREIGN_RATE', 'SETTLEMENT_DUE_DAYS', 'SETTLEMENT_DISC_RATE', 'FOREIGN_SETTLEMENT_DISC_AMOUNT', 'FOREIGN_SETTLEMENT_TOTAL', 'SETTLEMENT_DISC_AMOUNT', 'SETTLEMENT_TOTAL', 'PAYMENT_REF', 'PRINTED', 'PRINTED_CODE', 'POSTED', 'POSTED_CODE', 'QUOTE_STATUS_ID', 'RECURRING_REF', 'DUNS_NUMBER', 'PAYMENT_TYPE', 'BANK_REF', 'GDN_NUMBER', 'PROJECT_ID', 'ANALYSIS_1', 'ANALYSIS_2', 'ANALYSIS_3', 'INVOICE_PAYMENT_ID', 'RESUBMIT_INVOICE_PAYMENT_REQUIRED', 'RECORD_CREATE_DATE', 'RECORD_MODIFY_DATE', 'RECORD_DELETED' FROM 'PURCHASE_ORDER' WHERE ORDER_DATE >='{0}' and ORDER_DATE <='{1}'";
int counter = 0;
using (var command = new OdbcCommand(string.Format(SQL, fromD, toD), connection))
{
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
var purhcaseOrders = new PurchaseLinkHeaderC();
if ((reader["ORDER_NUMBER"] != ""))
{
counter++;
string orderNumber = Convert.ToString(reader["ORDER_NUMBER"]);
purhcaseOrders.Order_Number = OrderNumber.ToString();
purhcaseOrders.PurchaseOrderNo = Convert.ToInt32(reader["ORDER_NUMBER"]);
purhcaseOrders.Name = reader["NAME"].ToString();
purhcaseOrders.Selected_PurchaseOrder = false;
_purhcaseOrderList.Add(purhcaseOrders);
}
}
}
}
}
}
catch (Exception ex)
{
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info(ex, "Error at GetSalesOrders " + ex.ToString());
}
return _purhcaseOrderList;
}
I want to be able to show a progress bar of the list being loaded so I was attempting to call it as this way. But I am not sure how to attach the progress method either.
var progressIndicator = new Progress<int>(ReportProgress);
//call async method
BindingList<PurchaseLinkHeaderC> purchaseOrders = await GetPurchaseOrders(progressIndicator);
_masterPurchaseOrders = purchaseOrders;
I am hoping that someone can help here.
c# winforms async-await
c# winforms async-await
edited Nov 20 '18 at 9:38
GSerg
59.2k14102222
59.2k14102222
asked Nov 20 '18 at 9:24


daviddavid
114
114
What are you doing inGetPurchaseOrders()
method actually?
– Rahul
Nov 20 '18 at 9:25
@Rahul the GetPurchaseOrders is shown in its enterity above its going to odbc in sage to retrieve orders from the tables using odbc sql
– david
Nov 20 '18 at 9:31
You are not reporting any progress through yourIProgress<int>
. You should also see stackoverflow.com/q/332365/11683 for why you must not usestring.Format
to build a query.
– GSerg
Nov 20 '18 at 9:39
@GSerg that is the secondary issue main issue is the blocking of the ui
– david
Nov 20 '18 at 9:43
add a comment |
What are you doing inGetPurchaseOrders()
method actually?
– Rahul
Nov 20 '18 at 9:25
@Rahul the GetPurchaseOrders is shown in its enterity above its going to odbc in sage to retrieve orders from the tables using odbc sql
– david
Nov 20 '18 at 9:31
You are not reporting any progress through yourIProgress<int>
. You should also see stackoverflow.com/q/332365/11683 for why you must not usestring.Format
to build a query.
– GSerg
Nov 20 '18 at 9:39
@GSerg that is the secondary issue main issue is the blocking of the ui
– david
Nov 20 '18 at 9:43
What are you doing in
GetPurchaseOrders()
method actually?– Rahul
Nov 20 '18 at 9:25
What are you doing in
GetPurchaseOrders()
method actually?– Rahul
Nov 20 '18 at 9:25
@Rahul the GetPurchaseOrders is shown in its enterity above its going to odbc in sage to retrieve orders from the tables using odbc sql
– david
Nov 20 '18 at 9:31
@Rahul the GetPurchaseOrders is shown in its enterity above its going to odbc in sage to retrieve orders from the tables using odbc sql
– david
Nov 20 '18 at 9:31
You are not reporting any progress through your
IProgress<int>
. You should also see stackoverflow.com/q/332365/11683 for why you must not use string.Format
to build a query.– GSerg
Nov 20 '18 at 9:39
You are not reporting any progress through your
IProgress<int>
. You should also see stackoverflow.com/q/332365/11683 for why you must not use string.Format
to build a query.– GSerg
Nov 20 '18 at 9:39
@GSerg that is the secondary issue main issue is the blocking of the ui
– david
Nov 20 '18 at 9:43
@GSerg that is the secondary issue main issue is the blocking of the ui
– david
Nov 20 '18 at 9:43
add a comment |
1 Answer
1
active
oldest
votes
When you await
, the default behaviour is to use the sync-context, if one, when coming back from the async
operation. In the case of a UI application, the sync-context is: the UI.
So; right now, there are a lot of things that come back to the UI. This is useful when context matters, but in your case: it doesn't - since you are simply returning a list.
This means that you should be able to add .ConfigureAwait(false)
to a lot of those await
expressions - for example:
while (await reader.ReadAsync().ConfigureAwait(false))
This disconnects the sync-context behaviour, and may improve what you are seeing. You would ideally to add that to all of the await
calls in the utility method (GetPurchaseOrders
).
You may also wish to look for any missing async
operations - for example, the connection.Open();
could be a await connection.OpenAsync().ConfigureAwait(false);
Note that the calling code should not use ConfigureAwait(false)
- since the binding-list touches the UI, it needs the sync-context. So: don't add ConfigureAwait(false)
to the await GetPurchaseOrders(...)
call.
There is also one other possibility: you say that you are using ODBC and "sage". It is entirely possible that the ODBC/sage API doesn't support await
, and it is being implemented as "sync over async". If this is the case, it gets tricky. You might need to use a thread instead of async
/await
in that case - perhaps via ThreadPool.QueueUserWorkItem
. There are ways to invoke async
code on worker threads, but if the "async" code is actually "sync code that pretends to be async", there's not really any point, and you might as well do it "the old way". This usually means:
- start a worker (
ThreadPool
) - do some work on the worker (your existing code, but perhaps using the non-async implementation)
- at the end of the worker, use
Control.Invoke
to push the work back to the UI thread for the final "update the UI" step
Since the await captures sync-context, in this case UI, would there be any difference when the calling side usesawait Task.Run(Rest of the code here)
rather than addingConfigureAwait(false)
to every async operation in the library?
– Hasan Emrah Süngü
Nov 20 '18 at 9:45
@EmrahSüngü it "rest of the code here" includesawait
, then there's a good chance that without theConfigureAwait(false)
, it'll just come straight back to the UI at the first non-synchronousawait
– Marc Gravell♦
Nov 20 '18 at 10:00
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53389824%2faysnc-method-still-blocking-the-ui-interface%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
When you await
, the default behaviour is to use the sync-context, if one, when coming back from the async
operation. In the case of a UI application, the sync-context is: the UI.
So; right now, there are a lot of things that come back to the UI. This is useful when context matters, but in your case: it doesn't - since you are simply returning a list.
This means that you should be able to add .ConfigureAwait(false)
to a lot of those await
expressions - for example:
while (await reader.ReadAsync().ConfigureAwait(false))
This disconnects the sync-context behaviour, and may improve what you are seeing. You would ideally to add that to all of the await
calls in the utility method (GetPurchaseOrders
).
You may also wish to look for any missing async
operations - for example, the connection.Open();
could be a await connection.OpenAsync().ConfigureAwait(false);
Note that the calling code should not use ConfigureAwait(false)
- since the binding-list touches the UI, it needs the sync-context. So: don't add ConfigureAwait(false)
to the await GetPurchaseOrders(...)
call.
There is also one other possibility: you say that you are using ODBC and "sage". It is entirely possible that the ODBC/sage API doesn't support await
, and it is being implemented as "sync over async". If this is the case, it gets tricky. You might need to use a thread instead of async
/await
in that case - perhaps via ThreadPool.QueueUserWorkItem
. There are ways to invoke async
code on worker threads, but if the "async" code is actually "sync code that pretends to be async", there's not really any point, and you might as well do it "the old way". This usually means:
- start a worker (
ThreadPool
) - do some work on the worker (your existing code, but perhaps using the non-async implementation)
- at the end of the worker, use
Control.Invoke
to push the work back to the UI thread for the final "update the UI" step
Since the await captures sync-context, in this case UI, would there be any difference when the calling side usesawait Task.Run(Rest of the code here)
rather than addingConfigureAwait(false)
to every async operation in the library?
– Hasan Emrah Süngü
Nov 20 '18 at 9:45
@EmrahSüngü it "rest of the code here" includesawait
, then there's a good chance that without theConfigureAwait(false)
, it'll just come straight back to the UI at the first non-synchronousawait
– Marc Gravell♦
Nov 20 '18 at 10:00
add a comment |
When you await
, the default behaviour is to use the sync-context, if one, when coming back from the async
operation. In the case of a UI application, the sync-context is: the UI.
So; right now, there are a lot of things that come back to the UI. This is useful when context matters, but in your case: it doesn't - since you are simply returning a list.
This means that you should be able to add .ConfigureAwait(false)
to a lot of those await
expressions - for example:
while (await reader.ReadAsync().ConfigureAwait(false))
This disconnects the sync-context behaviour, and may improve what you are seeing. You would ideally to add that to all of the await
calls in the utility method (GetPurchaseOrders
).
You may also wish to look for any missing async
operations - for example, the connection.Open();
could be a await connection.OpenAsync().ConfigureAwait(false);
Note that the calling code should not use ConfigureAwait(false)
- since the binding-list touches the UI, it needs the sync-context. So: don't add ConfigureAwait(false)
to the await GetPurchaseOrders(...)
call.
There is also one other possibility: you say that you are using ODBC and "sage". It is entirely possible that the ODBC/sage API doesn't support await
, and it is being implemented as "sync over async". If this is the case, it gets tricky. You might need to use a thread instead of async
/await
in that case - perhaps via ThreadPool.QueueUserWorkItem
. There are ways to invoke async
code on worker threads, but if the "async" code is actually "sync code that pretends to be async", there's not really any point, and you might as well do it "the old way". This usually means:
- start a worker (
ThreadPool
) - do some work on the worker (your existing code, but perhaps using the non-async implementation)
- at the end of the worker, use
Control.Invoke
to push the work back to the UI thread for the final "update the UI" step
Since the await captures sync-context, in this case UI, would there be any difference when the calling side usesawait Task.Run(Rest of the code here)
rather than addingConfigureAwait(false)
to every async operation in the library?
– Hasan Emrah Süngü
Nov 20 '18 at 9:45
@EmrahSüngü it "rest of the code here" includesawait
, then there's a good chance that without theConfigureAwait(false)
, it'll just come straight back to the UI at the first non-synchronousawait
– Marc Gravell♦
Nov 20 '18 at 10:00
add a comment |
When you await
, the default behaviour is to use the sync-context, if one, when coming back from the async
operation. In the case of a UI application, the sync-context is: the UI.
So; right now, there are a lot of things that come back to the UI. This is useful when context matters, but in your case: it doesn't - since you are simply returning a list.
This means that you should be able to add .ConfigureAwait(false)
to a lot of those await
expressions - for example:
while (await reader.ReadAsync().ConfigureAwait(false))
This disconnects the sync-context behaviour, and may improve what you are seeing. You would ideally to add that to all of the await
calls in the utility method (GetPurchaseOrders
).
You may also wish to look for any missing async
operations - for example, the connection.Open();
could be a await connection.OpenAsync().ConfigureAwait(false);
Note that the calling code should not use ConfigureAwait(false)
- since the binding-list touches the UI, it needs the sync-context. So: don't add ConfigureAwait(false)
to the await GetPurchaseOrders(...)
call.
There is also one other possibility: you say that you are using ODBC and "sage". It is entirely possible that the ODBC/sage API doesn't support await
, and it is being implemented as "sync over async". If this is the case, it gets tricky. You might need to use a thread instead of async
/await
in that case - perhaps via ThreadPool.QueueUserWorkItem
. There are ways to invoke async
code on worker threads, but if the "async" code is actually "sync code that pretends to be async", there's not really any point, and you might as well do it "the old way". This usually means:
- start a worker (
ThreadPool
) - do some work on the worker (your existing code, but perhaps using the non-async implementation)
- at the end of the worker, use
Control.Invoke
to push the work back to the UI thread for the final "update the UI" step
When you await
, the default behaviour is to use the sync-context, if one, when coming back from the async
operation. In the case of a UI application, the sync-context is: the UI.
So; right now, there are a lot of things that come back to the UI. This is useful when context matters, but in your case: it doesn't - since you are simply returning a list.
This means that you should be able to add .ConfigureAwait(false)
to a lot of those await
expressions - for example:
while (await reader.ReadAsync().ConfigureAwait(false))
This disconnects the sync-context behaviour, and may improve what you are seeing. You would ideally to add that to all of the await
calls in the utility method (GetPurchaseOrders
).
You may also wish to look for any missing async
operations - for example, the connection.Open();
could be a await connection.OpenAsync().ConfigureAwait(false);
Note that the calling code should not use ConfigureAwait(false)
- since the binding-list touches the UI, it needs the sync-context. So: don't add ConfigureAwait(false)
to the await GetPurchaseOrders(...)
call.
There is also one other possibility: you say that you are using ODBC and "sage". It is entirely possible that the ODBC/sage API doesn't support await
, and it is being implemented as "sync over async". If this is the case, it gets tricky. You might need to use a thread instead of async
/await
in that case - perhaps via ThreadPool.QueueUserWorkItem
. There are ways to invoke async
code on worker threads, but if the "async" code is actually "sync code that pretends to be async", there's not really any point, and you might as well do it "the old way". This usually means:
- start a worker (
ThreadPool
) - do some work on the worker (your existing code, but perhaps using the non-async implementation)
- at the end of the worker, use
Control.Invoke
to push the work back to the UI thread for the final "update the UI" step
edited Nov 20 '18 at 10:01
answered Nov 20 '18 at 9:37


Marc Gravell♦Marc Gravell
780k19421342543
780k19421342543
Since the await captures sync-context, in this case UI, would there be any difference when the calling side usesawait Task.Run(Rest of the code here)
rather than addingConfigureAwait(false)
to every async operation in the library?
– Hasan Emrah Süngü
Nov 20 '18 at 9:45
@EmrahSüngü it "rest of the code here" includesawait
, then there's a good chance that without theConfigureAwait(false)
, it'll just come straight back to the UI at the first non-synchronousawait
– Marc Gravell♦
Nov 20 '18 at 10:00
add a comment |
Since the await captures sync-context, in this case UI, would there be any difference when the calling side usesawait Task.Run(Rest of the code here)
rather than addingConfigureAwait(false)
to every async operation in the library?
– Hasan Emrah Süngü
Nov 20 '18 at 9:45
@EmrahSüngü it "rest of the code here" includesawait
, then there's a good chance that without theConfigureAwait(false)
, it'll just come straight back to the UI at the first non-synchronousawait
– Marc Gravell♦
Nov 20 '18 at 10:00
Since the await captures sync-context, in this case UI, would there be any difference when the calling side uses
await Task.Run(Rest of the code here)
rather than adding ConfigureAwait(false)
to every async operation in the library?– Hasan Emrah Süngü
Nov 20 '18 at 9:45
Since the await captures sync-context, in this case UI, would there be any difference when the calling side uses
await Task.Run(Rest of the code here)
rather than adding ConfigureAwait(false)
to every async operation in the library?– Hasan Emrah Süngü
Nov 20 '18 at 9:45
@EmrahSüngü it "rest of the code here" includes
await
, then there's a good chance that without the ConfigureAwait(false)
, it'll just come straight back to the UI at the first non-synchronous await
– Marc Gravell♦
Nov 20 '18 at 10:00
@EmrahSüngü it "rest of the code here" includes
await
, then there's a good chance that without the ConfigureAwait(false)
, it'll just come straight back to the UI at the first non-synchronous await
– Marc Gravell♦
Nov 20 '18 at 10:00
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53389824%2faysnc-method-still-blocking-the-ui-interface%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
What are you doing in
GetPurchaseOrders()
method actually?– Rahul
Nov 20 '18 at 9:25
@Rahul the GetPurchaseOrders is shown in its enterity above its going to odbc in sage to retrieve orders from the tables using odbc sql
– david
Nov 20 '18 at 9:31
You are not reporting any progress through your
IProgress<int>
. You should also see stackoverflow.com/q/332365/11683 for why you must not usestring.Format
to build a query.– GSerg
Nov 20 '18 at 9:39
@GSerg that is the secondary issue main issue is the blocking of the ui
– david
Nov 20 '18 at 9:43