- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
如果给定的记录处理失败,我有一个异步调用会抛出异常。该异常作为聚合异常被捕获。现在,我必须从我的异步方法中记录一条警告消息。我无法登录到 TextBox/Grid,因为它不允许访问不同线程的控件,而且我无法抛出异常,因为我实际上想记录并继续该任务。这是启动任务的父代码:
private List<OrganizationUser> GenerateDataList(string importFilePath, int lastUserId = -1)
{
var resultList = new List<OrganizationUser>();
// Note: ReadLine is faster than ReadAllLines
var lineCount = File.ReadLines(importFilePath).Count();
LogMessage(new LogEntry(String.Format(" - File has {0} lines.", lineCount)));
var consistancyCounter = 0;
ResetProgress();
using (var fs = File.Open(importFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var bs = new BufferedStream(fs))
{
using (var sr = new StreamReader(bs))
{
string readLine;
while ((readLine = sr.ReadLine()) != null)
{
if (string.IsNullOrEmpty(readLine) || readLine == "---EOF---")
{
break;
}
try
{
var processLineTask = Task.Run(() => GenerateDataListInternal(nextId++, localReadLine, localConsistancyCounter));
processLineTask.Wait();
var result = processLineTask.Result;
if (result != null)
{
resultList.Add(result);
}
}
catch (AggregateException exp)
{
if (exp.InnerExceptions.Count == 1 && exp.InnerExceptions.Any(x => x is DataFileBadColumnNumbers || x is DataFileGenerateListException))
{
LogMessage(new LogEntry(exp.InnerExceptions[0].Message, LogEntryType.Warning));
}
else if (exp.InnerExceptions.Count == 1 && exp.InnerExceptions.Any(x => x is IndexOutOfRangeException))
{
LogMessage(new LogEntry(String.Format(" - Data cannot be parsed at line #{0}. Data is: {1}", localConsistancyCounter + 1, localReadLine), LogEntryType.Warning));
}
else
{
throw;
}
}
}
if (ProgressBarImport.Value <= ProgressBarImport.Maximum)
{
ProgressBarImport.PerformStep();
}
}
}
}
}
上面代码中,GenerateDataListInternal
是抛出异常的方法,现在需要记录。
如何从 GenerateDataListInternal
方法中登录?我已经尝试过委托(delegate)方法,只是挂起应用程序。我有一个记录到控制台、网格和文本文件(按此顺序)的方法。由于跨线程操作,从异步方法对该方法的任何调用都会失败。
最佳答案
这已经通过 System.IProgress 提供了接口(interface)和 Progress类,其中 T
可以是任何类(class),让您报告的不仅仅是简单的进度百分比。
IProgress<T>.Report
允许您从异步操作内部报告进度(或其他任何内容),而不必担心谁将实际处理报告。
Progress<T>
每当您的任务调用 .Report
时,将在创建它的线程(例如 UI 线程)上调用一个操作和/或引发一个事件。
这个例子来自.NET Framework Blog显示使用起来有多么容易 IProgress<T>
:
async Task<int> UploadPicturesAsync(List<Image> imageList, IProgress<int> progress)
{
int totalCount = imageList.Count;
int processCount = await Task.Run<int>(() =>
{
int tempCount = 0;
foreach (var image in imageList)
{
//await the processing and uploading logic here
int processed = await UploadAndProcessAsync(image);
if (progress != null)
{
progress.Report((tempCount * 100 / totalCount));
}
tempCount++;
}
return tempCount;
});
return processCount;
}
异步进程从这段代码开始:
private async void Start_Button_Click(object sender, RoutedEventArgs e)
{
//construct Progress<T>, passing ReportProgress as the Action<T>
var progressIndicator = new Progress<int>(ReportProgress);
//call async method
int uploads=await UploadPicturesAsync(GenerateTestImages(), progressIndicator);
}
请注意 progressIndicator
在 UI 线程中创建,所以 ReportProgress
方法将在 UI 线程上调用。
更新
从评论来看,您似乎正在尝试创建自己的日志记录解决方案,但在从多个线程访问日志文件时遇到了问题。
这里最好的解决方案是使用像 log4net
这样的日志库, NLog
甚至.NET 的诊断类。所有这些都可以在多线程下正常工作。
IProgress<T>
在这里仍然可以提供帮助,因为处理 Report 事件的委托(delegate)可以简单地将消息写入您已经在 UI 线程上创建的日志文件。
你可以这样写:
var progress = new Progress<LogEntry>(entry =>
{
_logFile.WriteLine("{0} : {1}",entry.EntryType,entry.Message);
});
并从任务内部报告:
var entry=new LogEntry(...);
progress.Report(entry);
关于c# - 在任务中报告/记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23518593/
@After public void afterScenario() { if (ScenarioManager.getScenario().isFailed()) {
我已将 BIRT 报告集成到 Grails 中并设计了一份报告。我的 grails 应用程序中有一个名为 startPeriod (仅限月份和年份)的参数,我想将其传递给 BIRT。然后 BIRT 调
我有一些 Oracle 报告 (.rdf),正在考虑将其转换为 BIRT 报告。有没有办法将 .rdf 文件转换为 BIRT 报告设计文件? 最佳答案 完全自动化的解决方案可能是不可能的。您可以部分自
当 gcc 4.1(使用 gcov)下一行: p = 新类; 报告为 100% 分支覆盖率 为什么? 因为启用了异常处理!!! 为了解决此问题,请指定: -fno-exceptions 在 g++
真的有好 免费 BugZilla 报告工具?我发现 Web 界面上的默认搜索选项太有限了。我最大的问题是缺少 Order By 选项(一次只有 1 个字段,可供选择的字段集非常有限)。我已经做了一些谷
是否可以在 CFMX7 上运行 ColdFusion Report builder 生成的报告? 更明确地说,是否可以将 CF7 中的报告生成引擎更改为 CF8? 最佳答案 我猜这可能很难做到。我记得
根据Lucintel发布的新市场报告,智能家居市场的未来看起来很有吸引力,在家用安全、家电、娱乐、照明、HVAC、医疗保健和厨房应用中将带来许多机遇。 由于COVID-19导致的全球经济衰退,
PHPCodeSniffer 是否生成 HTML 报告? 如果不是呢?怎么办? 目前,我可以运行 PHPCodeSniffer,但它只生成 XML 文件并在终端中显示结果。 如何在 phpunit 中
我在一个包中添加了一个简单的测试。 按照手册中的建议,我尝试让 PHPUnit 加载配置: phpunit -c /app phpunit.xml 看起来像这样:
我有两个从 csv 文件加载的数据框。基本上来自不同的环境但格式/列相似,它们的行/值可能有所不同。我想找到差异并在新的数据框中创建它们。两个数据框也将具有相同的顺序。我有 100 个要比较的文件。提
我想看看是否有办法通过 javadoc 在我的 junit 报告中包含“描述性文本”。 JUnit 4 似乎不像 TestNG 那样支持 @Test 注释的“描述”属性。 到目前为止,我所研究的只有一
我正在使用操作、 Controller 、servlet struts 框架编写 Excel 报告。该报告非常拥挤,已经有大约 10 个单独的查询。由于报告发生变化,我需要再添加大约 10 个查询。有
在放弃 Syleam 的 openerp jasper 模块后,我在 Nan Tic 的 jasper_reports 模块上苦苦挣扎。 它一直给我一个错误: File "C:\Program Fil
我希望创建一个简单的日历。每天由编码器生成条目计数并以日历样式查看。如一月、二月等。或按月显示全年。 database have date_added and encoder columns 我在将它
我必须为报告创建 MySQL 查询。 我有一个表history,它记录产品订单的状态更改。我有订单生命周期(订单流程)的以下状态:新、已确认、正在处理、已发货、已交付、已取消、已退回。订单不一定遵循此
如何将多个查询合并为一个? 例如: //Successful Sales: SELECT username, count(*) as TotalSales, sum(point) as Points
MySQL 优化技术的新手。请找到下面的 mysqltuner.pl 报告,并建议我应该更改 my.cnf 中的哪些变量以优化性能。 还有一个问题- 我无法在我的 my.cnf 中找到一些变量,例如
我想知道,我想将我的 Swing Worker 的某种形式的进度报告回主线程,以便我的界面可以使用随着进度增加而变化的标签进行更新,例如 checking 1/6... checking 2/6...
我正在尝试在“报告”>“销售”下运行 Magento Paypal 结算报告,但每次我尝试运行该报告时,我都会收到消息“由于配置为空,无法获取任何内容” 我查看了“系统”>“配置”>“销售”>“付款方
我想要一个工具来帮助创建 sql 查询(对于非 IT 人员),例如 dbforge。 我希望我们的非 IT 人员(例如运营)创建他们自己的 sql 查询。 我的第二个目标是让他们能够按需执行这些查询。
我是一名优秀的程序员,十分优秀!