gpt4 book ai didi

c# - 阻塞 ForEach 直到异步事件完成

转载 作者:行者123 更新时间:2023-12-03 12:49:31 29 4
gpt4 key购买 nike

我正在使用 ReportViewer 控件和自定义打印作业工作流程,这给我带来了一些问题。我的代码看起来有点像这样:

        ids.ForEach(delegate(Guid? guid)
{
var details = items.Where(e => e.guid == guid);

var ds = new ReportDataSource("Form", details);
ReportViewer.LocalReport.DataSources.Clear();
ReportViewer.LocalReport.DataSources.Add(ds);
ReportViewer.RefreshReport();

});

当最终调用 RefreshReport() 时,它会触发其 RenderingComplete 事件,在该事件中,我有逻辑对打印作业进行排队:

        if (DisplayPrintDialog) ReportViewer.PrintDialog();
else
{
var document = new PrintDocument(ReportViewer.LocalReport);
document.PrinterSettings = ReportViewer.PrinterSettings;
document.Print();
}
DisplayPrintDialog = false;

问题是 ForEach 循环在 RenderingComplete 事件触发之前完成运行,因此我需要一种方法来阻止 ForEach 循环,直到循环的每次传递都触发 RenderingComplete 事件。解决这个问题的好方法是什么?

最佳答案

如果您必须将其保留在 foreach 中,请使用 AutoResetEvent .

// Define this elsewhere in your class
static AutoResetEvent reset = new AutoResetEvent(false);

// This assumes RenderingComplete takes 1 argument,
// and you aren't going to use it. If you are, change
// the _ to something more meaningful.
ReportViewer.RenderingComplete += _ =>
{
// This happens after the code below, and this tells the "WaitOne"
// lock that it can continue on with the rest of the code.
reset.Set();
}

ids.ForEach(guid =>
{
var details = items.Where(e => e.guid == guid);

var ds = new ReportDataSource("Form", details);
ReportViewer.LocalReport.DataSources.Clear();
ReportViewer.LocalReport.DataSources.Add(ds);

// Begin the async refresh
ReportViewer.RefreshReport();

reset.WaitOne(); // This call will block until "reset.Set()" is called.
reset.Reset(); // This resets the state for the next loop iteration.
});

我也冒昧地让你的匿名委托(delegate)变得不那么难看(此时没有真正的理由再使用关键字delegate,你应该使用简写() => { ... } 代替)。

关于c# - 阻塞 ForEach 直到异步事件完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16844704/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com