The function works when called synchronously, but does not work when called asynchronously

This is my first StackOverflow forum post, so please be lenient. I have a problem with a function that works synchronously but does not work asynchronously. Below you will find the function synchronously:

private void issueInvoices(List<int> lista) { foreach (int knh_id in lista) { Invoice fs = new Invoice(); fs.FKS_AKCYZA = false; fs.FKS_CZY_KLON = false; fs.FKS_DATE = Convert.ToDateTime(MTBDataZapisuDoFK.Text); fs.NUMBER = knh_id); } } 

As you can see, I passed a list of functions called issueInvoices a list of account numbers, and in the loop I created several invoices. This function works correctly, but if I try to call it asynchronously (to display a progress bar), my function cannot assign fs.FKS_DATE to a dateTime object. It looks like the static function "Convert.ToDateTime" is not working properly. But please see below code where the function issueInvoices is called asynchronously ...

 public delegate void BinaryDelegate(List<int> knh_id); BinaryDelegate b = new BinaryDelegate(issueInvoices); IAsyncResult theAsRes = b.BeginInvoke(lista, new AsyncCallback(AddComplete), "Thx U!"); FrmProgressBar fpb=new FrmProgressBar("Please wait…"); fpb.Show(); /* below i check how many operation i have to do, if all operations are done, then I close fpb window, program is updating progres bar and in thread make operation issueInvoices*/ while (ilosc_zrobionych != liczbaKontrahentow) { fpb.PBStan.Value = (int)((100 * ilosc_zrobionych) / liczbaKontrahentow); } fpb.Close(); 

I put some breakpoints, and it is like stopping a program in a string, it can convert to datetime, but when I do it synchronously, it works without errors. fs.FKS_DATE = Convert.ToDateTime (MTBDataZapisuDoFK.Text); What can solve this problem and how to solve it? Thanks so much in advance for your reply.

BELOW THE TARGET CLASS IS CALLED FOR FREE:

 using System; using System.Collections.Generic; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Npgsql; using Castle.ActiveRecord; using WFR.Model; using System.Threading; namespace Faktury_i_Rachunki_2.Forms { public partial class FrmEmisjaFakturPotwierdzonych : FrmBaseForm { private ArrayList listaSposobowZaplaty; public List<int> lista; private int liczbaWygenerowach; private int liczbaKontrahentow; private int ilosc_zrobionych; private FrmProgressBar fpb; public delegate void BinaryDelegate(List<int> knh_id); public FrmEmisjaFakturPotwierdzonych() { InitializeComponent(); fpb = new FrmProgressBar("Please wait...."); } private void BtOK_Click(object sender, EventArgs e) { BinaryDelegate b = new BinaryDelegate(WyemitujFakture); lista.Add(12); lista.Add(13); lista.Add(17); lista.Add(1); liczbaKontrahentow = lista.Count; if (TBRejestr.Text.Trim() != "") { if (liczbaKontrahentow > 0) { liczbaWygenerowach = 0; ilosc_zrobionych = 0; WyemitujFakture(lista); IAsyncResult theAsRes = b.BeginInvoke(lista, new AsyncCallback(AddComplete), "THX"); fpb.Show(); while (ilosc_zrobionych != liczbaKontrahentow) { fpb.PBStan.Value = (int)((100 * ilosc_zrobionych) / liczbaKontrahentow); } fpb.Close(); } try { MessageBox.Show("Wygenerowano " + liczbaWygenerowach.ToString() + " faktur"); } catch { } } } private void WyemitujFakture(List<int> lista) { foreach (int knh_id in lista) { try { if (luk.Count > 0) { FakturySprzedazy fs = new FakturySprzedazy(); fs.FKS_AKCYZA = false; fs.FKS_CZY_KLON = false; fs.FKS_DATA_DOW_KS = Convert.ToDateTime(MTBDataZapisuDoFK.Text); fs.FKS_DATA_FAKTURY = Convert.ToDateTime(MTBDataFaktury.Text); fs.FKS_DATA_SPRZEDAZY = Convert.ToDateTime(MTBDataSprzedazy.Text); liczbaWygenerowach++; } } catch (Exception ex) { MessageBox.Show("Nie można wyemitować faktury dla kontrahenta o id = " + knh_id.ToString() + " " + ex.Message); } ilosc_zrobionych++; } } 
+4
source share
2 answers

The problem is getting the value of MTBDataZapisuDoFK.Text (which I assume as a text field). Getting or setting the text of a text field means sending messages to its window. But you keep the UI thread busy in the while loop and therefore you cannot process any messages.

Place a call to Application.DoEvents() in a while loop to enable message processing:

 fpb.Show(); while (ilosc_zrobionych != liczbaKontrahentow) { Application.DoEvents(); fpb.PBStan.Value = (int)((100 * ilosc_zrobionych) / liczbaKontrahentow); } fpb.Close(); 

I assume that the only reason for calling the method asynchronously is the ability to update the interface while processing the WyemitujFakture method. Using Application.DoEvents() , you do not need asynchronous calls:

 fpb = new FrmProgressBar("Please wait...."); fpb.Show(); Application.DoEvents(); WyemitujFakture(lista); fpb.Close(); 

You should call Application.DoEvents() after calling fpb.Show() so that the form displays correctly. You should also create an instance of the form in the method itself instead of the constructor, because you cannot use the same instance again after calling fpb.Close() (it will be deleted).

Then you can update the progress bar in the WyemitujFakture method:

 private void WyemitujFakture(List<int> lista) { foreach (int knh_id in lista) { try { if (luk.Count > 0) { FakturySprzedazy fs = new FakturySprzedazy(); fs.FKS_AKCYZA = false; fs.FKS_CZY_KLON = false; fs.FKS_DATA_DOW_KS = Convert.ToDateTime(MTBDataZapisuDoFK.Text); fs.FKS_DATA_FAKTURY = Convert.ToDateTime(MTBDataFaktury.Text); fs.FKS_DATA_SPRZEDAZY = Convert.ToDateTime(MTBDataSprzedazy.Text); liczbaWygenerowach++; } } catch (Exception ex) { MessageBox.Show("Nie mozna wyemitowac faktury dla kontrahenta o id = " + knh_id.ToString() + " " + ex.Message); } ilosc_zrobionych++; fpb.PBStan.Value = (int)((100 * ilosc_zrobionych) / liczbaKontrahentow); Application.DoEvents(); } } 
+1
source

You access the user interface control from the background thread:

 MTBDataZapisuDoFK.Text 

This is not allowed.

Get this value before calling the method, save it in a variable, and send the value as argument to issueInvoices .

+3
source

Source: https://habr.com/ru/post/1434344/


All Articles