【发布时间】:2018-09-13 14:09:42
【问题描述】:
我正在开展一个项目,该项目基本上运行扫描并根据某些正则表达式确定目录中是否存在敏感信息。在这个项目中,我们有一个名为 DataScannerUI 的主项目 (WPF) 和一个名为 FileScanCore 的类库。 FileScanCore 被引用到 DataScannerUI。
简介:
这就是我的项目的运作方式。所有与扫描相关的逻辑都写在 FileScanCore 中,然后在调用它时将由此生成的结果集传递到 DataScannerUI。下面是扫描层次结构:-
- 我定义了一个需要扫描的来源。
- 扫描源目录(根目录到子目录:这只是查找需要扫描的路径的标识号。)
- 在数据库中清点扫描结果。
- 收集从 DB 清点的所有路径。
- 根据库存路径执行深度扫描。
- 将深度扫描结果保存在数据库中。
现在这里发生的事情是没有。 4 如果数据源大小小于 50k,则不需要太多时间即可完成。如果数据源大小为 600k,例如那么这大约需要 30 分钟。这里似乎 UI 被挂起,因为这里没有显示任何状态。我需要的是显示一些状态并让用户知道到目前为止已经加载了多少库存百分比。这很快就实现了。现在这就是我现在卡住的地方,所有状态消息逻辑都写在 DataScannerUI 中,问题是我无法在 FileScanCore 中引用 DataScannerUI(循环依赖问题)。
我需要将百分比从 FileScanCore 传递给 DataScannerUI。为了解决这个问题,我在谷歌上搜索并遇到了下面的线程。
- 线程 1:Raise event of other class library in c sharp
- 线程 2:Call delegate methods from another class
- 线程3:http://zetcode.com/lang/csharp/delegates/
// ctrl-f search for C# events
我尝试使用上面的方法,但前 2 个线程对我没有用,虽然第 3 个线程有效,但它不能满足我的需要。 Shared 是我需要进行更改的 sn-p。
文件扫描核心
// This method is written in DeepScanner class that implements IScanner
private Queue<string> BuildInventory(FileSystem fs, IList<string> paths, bool includeChildren)
{
var previousProgressStatus = 0L;
var totalPathProcessed = 0L;
var filesToInventory = new Stack<string>();
var filesToDeepScan = new Queue<string>();
//files To Inventory logic is written here.
{
...
...
...
}
// Here we find all directory and files
foreach (var c in fs.GetChildren(currentPath))
{
// This is where I determine the percentage completed
var progressStatus = Math.Abs((totalPathProcessed++) * 100 / fs.TotalCount);
previousProgressStatus = ((progressStatus == previousProgressStatus) ? previousProgressStatus : progressStatus);
filesToInventory.Push(c.FullPath);
// I am looking for something that can trigger from here
// and send percentage change to DataScannerUI.
}
}
DataScannerUI
// This method is written in Scan class
foreach (var dataSource in _dataSources)
{
try
{
_scanRunSemaphore.WaitAsync(_cancelSource.Token);
ActiveDataSource = dataSource;
_status = $"Performing deep scan - {ActiveDataSource.Name}";
AllDeepScanners[ActiveDataSource.Name] = new DeepScanner(processors, extractor, _fileTypes, Job.Settings.SkipBinaries);
ActiveScanner = AllDeepScanners[dataSource.Name];
ActiveFileSystem = UsedFileSystems[ActiveDataSource.Name];
// This is where I want to subscribe that event.
// ActiveScanner is a property of type IScanner
ActiveScanner.ScanAsync(ActiveFileSystem, _cancelSource.Token, _pauseSource.Token).Wait(); // This is where the inventory gets loaded.
_status = $"Saving deep scan results - {ActiveDataSource.Name}";
_logger.Debug($"Storing Deep scan results belonged to data source '{dataSource.Name}'");
dataSource.SaveDeepScanResults(ActiveFileSystem, services);
_logger.Debug($"Storing Job Last Scanned info belonged to data source '{dataSource.Name}'");
SaveLastScanned(services, dataSource);
}
// I'm not mentioning catch block
}
我不确定我正在寻找的东西是否可能,但值得一试。
注意:如果这还不够,请发表评论,我将尝试使其更具解释性和可读性。
【问题讨论】:
-
“这里好像 UI 挂了,因为这里没有显示任何状态” 那是因为你在
.Wait()ing 一个异步调用,你不应该使用 @987654328 @如果你想要异步。添加事件并不能解决这个问题,UI 线程已经被锁定。 -
@RonBeyer:不知道为什么在这里使用
.wait()。这段代码是由其他开发人员编写的。
标签: c# wpf delegates event-handling