这是我在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();
我放了一些断点,它看起来像程序停止排队,它可以转换到日期时间,但是当我同步这样做时,它没有任何错误。 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++;
}
}
答案 0 :(得分:3)
您正在从后台线程访问UI控件:
MTBDataZapisuDoFK.Text
这是不允许的。
在调用方法之前获取此值,将其存储在变量中并将值作为参数发送到issueInvoices
。
答案 1 :(得分: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
- 方法期间更新UI。使用Application.DoEvents()
您不需要异步调用:
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();
}
}