- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个多线程 C# 应用程序,它创建文件,打开它们进行处理,然后在完成后删除它们。此应用程序可以预期处理 1 - 100 个文件。有点随机(很可能归因于应用程序的多线程性质)当我尝试在处理后删除文件时遇到共享冲突。我的直觉告诉我,维克,你在尝试删除文件之前没有正确关闭/处置文件。如果每个文件都发生这种情况,我会凭直觉去做,但事实并非如此。所以,我试图找出我在哪里犯了错误。外面有人对如何调试此类异常有任何指示吗?如果有意义的话,我很乐意在文件上看到堆栈跟踪。
我将尝试展示伪代码,但是,我的问题更多是关于如何调试此类异常:
申请事件:
操作开始 += 创建新处理器。
传输文件 += Processor.ProcessFile 并将新的文档对象添加到处理器的文档集合(作为路径,而不是文件)
操作完成 += Processor.Aggregate 文件,创建包含文件内容的新文件。当此方法完成时,它调用 ProcessorFinished。
处理器事件:
处理器完成 += Application_CleanUpProcessor。在这个方法中,我处理了处理器,处理器又处理了一个文档对象,该对象删除了文件。
最佳答案
承认您需要一种快速的方法来验证是否要花更多的时间调试您的代码,或者编写好的测试来证明您的代码是好的,您想要的是一种快速的方法来证明没有其他进程是使用你的文件。所以,让我们假设:
您希望能够运行您的程序,并查看导致您遇到共享冲突的那个文件发生了什么。
我会这样做:
Procmon 是一款出色的工具,您可以按顺序筛选出您希望在所有进程中看到的内容。 Link to procmon at sysinternals, from Microsoft
打开 procmon,为“路径”添加过滤器“开始于”“”
现在为“Result”“is”“SHARING VIOLATION”添加高亮显示
最后,运行程序直到出现异常,然后在路径列中右键单击共享冲突的文件,然后选择“在此处包含‘<文件名>’”以删除所有其他结果。您现在可以查看导致异常的文件的所有事件...
如果您想熟悉 procmon,这里是我用来为您伪造的代码。它有一个锁定文件的副线程,以及一个尝试锁定文件的主线程。只需创建一个 C# 控制台应用程序即可。它看起来像这样:
因此,在不到 2 分钟的时间内,您可以查看是您的代码有问题,还是其他原因。前几天我用它来确定我的 Com 组件实际上正在使用备用文件流,因此在它尝试使用网络驱动器时抛出异常。再多的单元测试也帮不了我。
这是强制共享违规的测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
internal class Program
{
private static int lockPoint = 0;
private static void Main(string[] args)
{
const string testFile = @"H:\test\test.txt";
FileInfo testFileInfo = new FileInfo(testFile);
if (!testFileInfo.Directory.Exists)
{
testFileInfo.Directory.Create();
}
// Clear our example
if (testFileInfo.Exists)
{
testFileInfo.Delete();
}
// Create the test file
using (FileStream fs = File.Create(testFile))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("test file content");
}
Task iLockTheFileFirst = new Task(() => {
using (FileStream fsThread = File.Open(testFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
Console.WriteLine("iLockTheFileFirst: I opened the file");
// Set lockPoint to 1 and let main try and open the file
Interlocked.Exchange(ref lockPoint, 1);
// Wait until the main thread sets lockPoint to 3
const int ifEqualTo3 = 3;
const int replaceWith4 = 4;
while (Interlocked.CompareExchange(ref lockPoint, replaceWith4, ifEqualTo3) != ifEqualTo3)
{
Console.WriteLine("iLockTheFileFirst: Waiting for main thread to let me finish");
Thread.Sleep(1000);
}
}
Console.WriteLine("iLockTheFileFirst: I have closed the file");
});
// Start the thread and lock the file
iLockTheFileFirst.Start();
// Now spin until the lockPoint becomes 1
const int ifEqualTo1 = 1;
const int replaceWith2 = 2;
// If lockPoint is equal to 1 (i.e. the main thread wants us to finish), then move it to 2
while (Interlocked.CompareExchange(ref lockPoint, replaceWith2, ifEqualTo1) != ifEqualTo1)
{
Console.WriteLine("Main thread: waiting for iLockTheFileFirst to open the file");
Thread.Sleep(1000);
}
try
{
Console.WriteLine("Main thread: now I'll try opening the file");
using (FileStream fsMain = File.Open(testFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
Console.WriteLine("Main thread: I opened the file, which shouldn't be possible");
}
}
catch (IOException ioex)
{
Console.WriteLine("Main thread: IOException: " + ioex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Main thread: some other exception: " + ex.Message);
}
// Set lockPoint to 3 and let other thread finish
Interlocked.Exchange(ref lockPoint, 3);
// Wait for other thread to finish
const int ifEqualTo4 = 4;
const int replaceWith5 = 5;
while (Interlocked.CompareExchange(ref lockPoint, replaceWith5, ifEqualTo4) != ifEqualTo4)
{
Thread.Sleep(10);
}
Console.WriteLine("Main thread: Press enter to finish");
Console.ReadLine();
}
}
这就是所有人!
关于c# - 如何在尝试删除文件时调试 "Sharing Violation",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15450860/
昨晚我因为这个问题脑子崩溃了。在确保没有来 self 的 eclipse 错误检查的明显错误之后,我开始调试我的程序。顺便说一下,我正在使用 Jre7。无论如何,每次我进入我的类调用(我们称之为“a”
(前言:我对 C/C++ 还很陌生,我真的不知道 native 代码中的调试实际上是如何工作的。) 一些消息来源说 gdb 和 lldb 可以调试 any program compiled to ma
我正在尝试从 Visual Studio 2012 外部调试 T4Scaffolding.Core Nuget 包。我使用的是安装了 Powershell 3.0 的 Powershell ISE,并
如何调试汇编代码?我在 Linux 上使用 gdb。我知道我可以看寄存器。有哪些调试汇编代码的方法? 最佳答案 您当然可以使用 breakpoints就像 C 或任何其他编译语言一样。 This ar
如何在每次通话时打印列表或 haskell 中的内容,例如: funct a list = funct (a + 1) (a : list) print list her
让我用我对 Makefiles 或 make 知之甚少的评论作为这个问题的前缀。 有一个非常大的项目,每晚自动构建。它以 Debug 和 Release 模式构建,Debug 用于 Valgrind
我正在创建一个计算每周工资的程序,那么任何加类工资都是该周正常工资的 1.5 倍。我的代码如下: #include int main() { double payrate; double h
我使用的是 Visual Studio 2010 Express Developer 版本。开发网站。我在我的 .aspx 页面中使用 JavaScript。 如何在 Javascript 中放置断点
我最近开始修补 Project Euler 问题,并尝试用 Javascript 解决它们。这样做我往往会产生许多无限循环,现在我想知道是否有比终止 Firefox 或 Chrome 中的选项卡更好的
有没有办法在程序执行期间生成一个交互式 python 控制台(最好是 iPython)而不暂停主程序并且能够检查和修改程序变量?类似于浏览器为 JavaScript 提供的功能。 我知道 pdb.se
我正在使用 FFmpeg @ Android 并希望能够进入 FFmpeg 代码(Eclipse + Seqouya),同时编译 FFmpeg 我使用 --disable-stripping --en
我从使用互操作调用 win32 api 函数的 .net 进程中得到一个异常。 我有一个调试器,我想查看 LastError 的值。 是否可以从 Visual Studio 调试器中查看 LastEr
我正在尝试通过 VBA 创建一个宏,以在 IE 的多个选项卡中打开一组指定的链接。目前我正在使用下面的代码,如果我试图打开 3 个或更少的选项卡,它大部分时间都可以工作。任何超过 3 的代码都会在“N
好的,这似乎是一个愚蠢的问题,因为 MonoDevelop 越来越成熟,所以我确定我只是想念它,但我环顾四周,所有关于这个主题的问题似乎都是关于远程调试或 Mac 上的调试。 我使用的是 Ubuntu
如何调试 Rscripts是从命令行运行的? 我目前正在使用 getopt传递命令行选项的包,当有错误时,我很难: 看看到底出了什么问题; 在 R 中交互式调试(因为脚本需要命令行选项。) 有没有人有
支持 PDF 和网络上的信息很少。我碰巧在博客中看到一篇文章,提到 $.write() 或 $.writeln() 将向 javascript 控制台写入一个字符串。相当有用。有谁知道这个 $ 对象是
PyCharm 1.5 中是否可以使用 Firefox 和 Chrome 支持的 JavaScript 调试? 如果是这样,它能否与 Python/Django 调试器一起有效运行? 如果没有,有没有
我确定这以前发生在人们身上,某些东西在 Debug模式下工作,你在发布时编译,但有些东西坏了。 这发生在我在嵌入式 XP 环境中工作时,我发现最好的方法确实是编写一个日志文件来确定它会出错的地方。 您
我目前正在为即将到来的项目评估 Flow3。 AOP 模式和依赖注入(inject)将非常适合我们的目的。 现在我想不通的是如何在 Controller Action 中调试一些结果。 public
最初,我有一个包含测试服务器的 Django 应用程序。要调试此设置,我只需添加 import pdb; pdb.set_trace()代码中的任何位置,并且有一个断点将我扔到终端中的交互式调试器中(
我是一名优秀的程序员,十分优秀!