当用户在主线程中处理对象时,在后台线程中处理对象
本文关键字:处理 对象 线程 后台 用户 | 更新日期: 2023-09-27 18:02:14
很抱歉写了这么久。
我有一个类(称为SceneryFile),其中包含很多元素。用户使用2D界面修改该类的内容。结果被编译成一个文件,在飞行模拟器应用程序中使用。用户操作可能导致编译失败的错误,或者编译成功但结果不能在模拟器中正常工作的警告。我想复制一些学位课程,如ReSharper或Just Code,在用户工作时检查后台SceneryFile的状态并报告错误。我试过使用后台工作器,但结果不可靠。
首先,我创建了一组参数传递给后台工作器,其中包含sceneryfile实例和其他一些东西:
public class FSIssueArgs {
public FSIssueArgs(SceneryFile sceneryFile, Airport airport) {
Issues = new Dictionary<string, FSIssue>();
SceneryFile = sceneryFile;
Airport = airport;
}
public FSIssueSeverity Severity { get; set; }
public Dictionary<string, FSIssue> Issues { get; set; }
public SceneryFile SceneryFile { get; private set; }
public Airport Airport { get; private set; }
}
每次后台工作线程完成时,我都在运行它。当加载文件时,我启动后台工作线程,然后在完成事件
中再次运行。private void onIssuesBackgroundWorkerRunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {
var args = e.Result as FSIssueArgs;
if (args != null) {
issueStatusLevel.BackColor = args.SceneryFile.IssueStatusFlag();
G.SceneryFile.Issues = args.Issues;
}
G.IssueHandlerActive = false;
check4Issues();
}
issueStatusLevel是一个按钮,它根据出现的错误和警告显示颜色。单击它将打开一个对话框,该对话框应列出所发现的问题。
check4Issues包含运行后台worker的调用
private void check4Issues() {
if (G.IssueHandlerActive) return;
G.IssueHandlerActive = true;
issuesFound = new Dictionary<string, FSIssue>();
var issueArgs = new FSIssueArgs(G.SceneryFile, G.CurrentAirport);
issuesBackgroundWorker.RunWorkerAsync(issueArgs);
}
指示灯按钮的颜色可靠地工作,但问题列表没有可靠地报告。如果按钮被点击并且列表对话框打开,我将停止后台worker的运行。
我确信问题是我不理解对象是如何在主线程和后台工作线程之间传递的。我希望对象(SceneryFile)传递给后台线程是一个副本,而不仅仅是一个引用。运行该文件中的一个方法来检查错误。错误存储在文件中。然后将该文件作为e.Result中参数的一部分发回。我现在认为我做错了,不知何故,我不应该在两个线程中使用相同的对象。
当然,当文件在后台验证时,用户正在前台修改它。
所以我想做的是将文件的副本发送到正在处理的后台线程,但不是主线程中对文件的引用。处理完后,我想发一份问题清单给你。我知道用户可能在此期间更改了文件,但我不太担心,下次运行会赶上它。
不清楚什么是风景文件对象类型真的是从代码,但而不是复制整个对象只是为了分析它,我建议保存指针位置,直到分析器必须扫描内容,文件或只是一个流。在这种情况下,您将拥有相同的文件/流,但在分析器和用户之间分开。
但是这里你应该处理多线程访问同一个源。
编辑你可以尝试为分析器设置一个只转发的流读取器,为用户设置一个只转发的流写入器。
希望对你有帮助。
问候。