2012-09-15 144 views
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異步調用...

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

我把一些斷點,它看起來像行程序回採,它可以CONVER爲datetime,但是當我這樣做同步,它的工作原理沒有任何錯誤。 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++; 
      } 
     } 
+1

這是很麻煩的代碼。如果你仍然有問題,請重寫使用BackgroundWorker並重新發布。 –

回答

1

問題是在獲取值MTBDataZapisuDoFK.Text(我認爲它是一個文本框)。獲取或設置文本框的文本意味着將消息發送到其窗口。但是你保持UI線程在while循環中忙,因此它不能處理任何消息。

將調用Application.DoEvents()進入while循環允許消息進行處理:

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

我假設調用該方法以異步方式的唯一原因是能夠處理WyemitujFakture期間更新UI -方法。使用Application.DoEvents()你不需要asynchonous電話:

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

你應該叫Application.DoEvents()你叫fpb.Show()後,允許適當的形式顯示出來。你也應該在方法本身而不是構造函數中實例化表單,因爲在調用fpb.Close()(它將被丟棄)之後你不能再次使用同一個實例。

然後你就可以在WyemitujFakture - 方法更新進度條:

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(); 
    } 
} 
+0

再次感謝您, 我檢查了您的提示,進度條正常工作,您的評論可以幫助我瞭解錯誤。 再次感謝你,祝你有美好的一天! 親切的問候 – JacekRobak85

3

你從後臺線程訪問UI控件:

MTBDataZapisuDoFK.Text 

這是不允許的。

在調用方法之前獲取此值,將其存儲在一個變量中並將該值作爲參數發送到issueInvoices

+0

不是這樣,可以從工作人員讀取Text屬性。不寫。 –