Riz*_*ama 2 c# wpf task dispatcher
首先,我要说的是,很难详细解释我的问题,但我会尽力。我将更新详细的解释或我使用的可能导致异常的更多代码。如果我的代码很混乱,我很抱歉。
我读过很多同名的问题,但我一点运气都没有。我对线程/任务/调度程序了解甚少,所以如果您发现我的代码有问题,请指导我。
简介
我的应用程序每n分钟通过计时器执行一次后台任务。
后台任务:从API获取数据,然后生成Window元素作为包含数据的表单,然后打印它们。
问题:目前该异常已发生两次,导致无法生成两个表单文档,因此无法打印它们。
获得的详细异常TaskScheduler.UnobservedTaskException是:
通过等待任务或访问其 Exception 属性都没有观察到任务的异常。结果,未观察到的异常被终结器线程重新抛出。
System.Collections.ObjectModel.ReadOnlyCollection`1[System.Exception]
这是我的一段代码,可能对您查找问题根源有用:
public void BackgroundTask(object sender, EventArgs e)
{
Application.Current.Dispatcher.Invoke(
new Action(GetInvoiceData),
DispatcherPriority.Background,
null
);
}
Run Code Online (Sandbox Code Playgroud)
...哪里GetInvoiceData:
public async void GetInvoiceData()
{
try
{
JsonData = await ApiHelperInstance.Post(ApiParam);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (!string.IsNullOrEmpty(JsonData))
{
var apiReturn = new ApiReturn();
try
{
apiReturn = JsonConvert.DeserializeObject<ApiReturn>(JsonData);
}
catch (JsonException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (apiReturn.Result != null)
{
foreach (ApiResult apiResult in apiReturn.Result)
{
InvoiceQueue.Enqueue(new Invoice(apiResult));
}
var worker = new BackgroundWorker();
worker.DoWork += GenerateDocumentAndPrint;
worker.RunWorkerAsync();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
...并且GenerateDocumentAndPrint是:
public void GenerateDocumentAndPrint(object sender, DoWorkEventArgs e)
{
while (InvoiceQueue.Count != 0)
{
Dispatcher.Invoke(() =>
{
Invoice invoice = InvoiceQueue.Dequeue();
var invoiceForm = new InvoiceForm();
var shippingLabelForm = new ShippingLabelForm();
invoiceForm.Dispatcher.Invoke(async () =>
{
var invoiceTmp = invoice;
var invoiceDoc = new FixedDocument();
try
{
invoiceDoc = await invoiceForm.CreateDocument(invoiceTmp);
}
finally
{
InvoiceDocumentName = PrintJobNameSub + " - Invoice #" + invoice.TransOrder.TransNumber;
PrintHelperInstance.SetPrinterByName(InvoicePrinterName);
PrintHelperInstance.PrintDocument(invoiceDoc.DocumentPaginator, InvoiceDocumentName);
invoiceForm.Close();
}
}, DispatcherPriority.ContextIdle);
shippingLabelForm.Dispatcher.Invoke(async () =>
{
var invoiceTmp = invoice;
var shippingLabelDoc = new FixedDocument();
try
{
shippingLabelDoc = await shippingLabelForm.CreateDocument(invoiceTmp);
}
finally
{
ShippingLabelDocumentName = PrintJobNameSub + " - Shipping Label #" + invoice.TransOrder.TransNumber;
PrintHelperInstance.SetPrinterByName(ShippingLabelPrinterName);
PrintHelperInstance.PrintDocument(shippingLabelDoc.DocumentPaginator, ShippingLabelDocumentName);
shippingLabelForm.Close();
}
}, DispatcherPriority.ContextIdle);
}, DispatcherPriority.Normal);
}
}
Run Code Online (Sandbox Code Playgroud)
CreateDocument...以及来自InvoiceForm和ShippingLabelFormcontains 的异步方法await Task.Delay(delay)。
我的代码有什么错误吗?是不是使用不当造成的Dispatcher.Invoke?是因为DispatcherPriorityenum使用错误造成的吗?是不是操作出了什么问题Task.Delay?
TaskScheduler.UnobservedTaskException当未观察到任务的异常时获取异常。如果您await完成所有任务,那么此事件将永远不会触发。
请注意,此事件并不一定意味着严格意义上的错误。例如,如果您放弃任务,则可能会发生这种情况 - 如果您的代码包含任何Task.WhenAny调用,则这种情况很常见。如果“即发即忘”任务抛出异常,也会发生这种情况。在这两种情况下,实际上都不是错误。在这种WhenAny情况下,另一个任务已经完成了Task.WhenAny,因此您不必关心另一个任务是否抛出异常。在“即发即忘”的情况下,“忘记”字面意思是“我不关心异常”,所以你不应该关心它是否抛出异常。
如果您意外丢失了await. 查找缺失的最简单方法await是检查内部异常的调用堆栈,然后检查该方法的调用者等,直到找到未正确await执行任务的方法。
| 归档时间: |
|
| 查看次数: |
4053 次 |
| 最近记录: |