4

StackOverflowフォーラムへの最初の投稿ですので、ご容赦ください。同期的に呼び出されて機能する関数に問題がありますが、非同期的に呼び出されて機能しません。以下に同期的に呼び出される関数があります。

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);
         }
    }

ご覧のとおり、請求書番号のissueInvoicesリストという名前の関数にリストを渡し、ループでいくつかの請求書を作成します。この関数は正しく機能しますが、非同期で(プログレスバーを表示するために)呼び出そうとすると、関数はfs.FKS_DATEオブジェクトのdateTimeに割り当てることができません。静的関数「Convert.ToDateTime」が正しく機能していないようです。ただし、関数issueInvoicesが非同期的に呼び出される以下のコードをご覧ください…</ p>

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();

いくつかのブレークポイントを設定すると、プログラムが一列に停止しているように見え、日時に変換できますが、これを同期的に実行すると、エラーなしで動作します。fs.FKS_DATE = Convert.ToDateTime(MTBDataZapisuDoFK.Text); この問題の原因とその解決方法は何でしょうか。返信ありがとうございます。

以下は、クラス全体が非同期で呼び出されます。

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

2 に答える 2

3

バックグラウンドスレッドからUIコントロールにアクセスしています。

MTBDataZapisuDoFK.Text

それは許可されていません。

メソッドを呼び出す前にこの値を取得し、それを変数に格納して、引数として値をに送信しますissueInvoices

于 2012-09-15T09:44:05.013 に答える
1

問題は、MTBDataZapisuDoFK.Text(テキストボックスであると想定している)の値を取得することです。テキストボックスのテキストを取得または設定することは、そのウィンドウにメッセージを送信することを意味します。ただし、whileループではUIスレッドをビジー状態に保つため、メッセージを処理できません。

呼び出しをApplication.DoEvents()whileループに入れて、メッセージを処理できるようにします。

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

メソッドを非同期的に呼び出す唯一の理由は、WyemitujFakture-methodの処理中にUIを更新できるようにするためだと思います。あなたを使用Application.DoEvents()することは非同期呼び出しを必要としません:

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

フォームが正しく表示されるようにするには、電話をかけApplication.DoEvents()た後に電話をかける必要があります。fpb.Show()また、呼び出し後に同じインスタンスを再度使用することはできないため、コンストラクターではなくメソッド自体でフォームをインスタンス化する必要がありますfpb.Close()(破棄されます)。

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();
    }
}
于 2012-09-15T15:41:03.793 に答える