【发布时间】:2022-07-04 18:36:24
【问题描述】:
我已经解决这个问题 3 个月了。
我在本机调试中遇到错误:
"在 FileReader.exe 中的 0x5A222FC2 (comct123.dll) 处引发异常: 0xC0000005:访问冲突读取位置0x0000000C。”
正常调试:
System.Windows.Forms.dll 中的“System.AccessViolationException”
我的设置很简单:
public static Form_Interface Interface;
public static void Initialize()
{
Application.SetCompatibleTextRenderingDefault(false);
Interface = new Form_Interface();
Interface.Filesdgv.DataSource = File.SortableBindingList;
Application.Run(Interface);
}
看起来很简单,对吧?不。 所以基本上我有一个简单的事件,它只是使用 Process.Start() 打开文件,无论我做什么,它都会在 System.Windows.Forms.dll 中随机崩溃,并出现“System.AccessViolationException”:
private void Filesdgv_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
Filesdgv.Invoke((Action)(() =>
{
try
{
int rowIndex = e.RowIndex;
if (rowIndex >= 0)
{
int columnIndex = e.ColumnIndex;
File file = (File)((DataGridView)sender).Rows[rowIndex].DataBoundItem;
switch (columnIndex)
{
case 0:
{
Process.Start(file.Location);
}
break;
}
}
}
catch
{
// This fking catch never works anyway.
}
}));
}
private void FileInterface_Load(object sender, EventArgs e)
{
foreach (string oCurrent in Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Files To Check")))
if (oCurrent.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
new File(oCurrent.Split('\\').Last(), oCurrent);
}
我打开文件/链接或其他任何东西都没有关系,它仍然以相同的方式运行。 链接和文件位置也是只读字段。
我有许多其他用途来读取行数据,它永远不会崩溃,即使我点击 10000 次垃圾邮件,它只会随机崩溃 Process.Start()
我尝试过的事情:
- 使用 BeginInvoke
- 使用调用
- 不使用 Invoke/BeginInvoke
- 在读取之前将文件链接放入字符串中。
- 使用多个 Try Catch
- 在另一台机器上重新编码...同样的结果。
- 我尝试使用 File.Open(要么不打开文件,要么抛出同样的错误 lmao)
- 尝试使用 [HandleProcessCorruptedStateExceptions],仍然无法捕获异常。
- 不管我点击慢还是快,仍然有 1/30 的机会发生。
- 尝试放置 Task.Run(() => Process.Start());您认为线程会保护您免受异常影响吗?没有仍然崩溃...
文件类如下所示:
public class File
{
public static SortableBindingList<File> SortableBindingList = new SortableBindingList<File>(new List<File>());
public readonly string fileName;
public readonly string filePath;
public void AddRow()
{
Client.Interface.Invoke((Action)(() =>
{
lock (SortableBindingList)
if (!SortableBindingList.Contains(this))
SortableBindingList.Add(this);
}));
}
public string FileName
{
get
{
return fileName;
}
}
public string Location
{
get
{
return filePath;
}
}
public File(string fileName, string filePath)
{
this.fileName = fileName;
this.filePath = filePath;
AddRow();
}
}
Initalize() 在静态 void Main(string[] args) 中调用。 没有其他线程在运行编辑或类似的东西,唯一运行的线程是表单线程。等待用户输入。
我正在寻找的解决方案:
- 启动文件/超链接的替代方法。
- 一种避免表单崩溃的方法(尝试 catch 样式)
【问题讨论】:
-
您应该为您在此处提供的 sn-p 提供上下文。 - 何时/何地调用
Initialize()?什么叫它?什么是List<File>?什么填充它,用什么填充?为什么要存储 Form 的静态实例?为什么要更改子控件的访问修饰符? -- 你到底为什么在事件处理程序中使用Invoke(),并使用引发事件的相同控件?你为什么要尝试调用? --Thread.Run()不存在,你的意思是Task.Run()-- 看起来你最终在某处取消引用空指针,丢失的上下文可能解释了它的原因/原因。 -
添加了更多细节,使用调用,因为我不知道问题是什么,但你说得对,我不需要它们。是的,我的意思是 Task.Run()
-
仍然缺少:什么填充 (
static) BindingList 以及何时/如何,因为它被初始化为空?为什么该表单声明为static?为什么 DGV 的访问修饰符设置为public?您是否尝试从其他地方访问该控件?是否可以从其他任何地方访问此表单?如果有,从哪里来? -- 如果您删除静态声明,并且您只是将 BindingList 传递给该表单的构造函数(添加一个接受SortableBindingList对象的构造函数),那么当前操作会发生什么变化? -
已编辑 Initialize(),我在某些时候需要将它们公开,因为我在 File 类中有更多属性来返回检测到的语言等,但我现在完全删除了它。哦,我还使用 Invoke 添加行。让我把它加到东西上。
-
好的,对不起,我不得不在我从头开始编写的两个版本之间切换,一个在我无法复制的 rdp 上,所以我不得不手动输入大部分内容。