【发布时间】:2018-09-18 01:54:26
【问题描述】:
我有一个在带有 Mono 的 Raspbian 上运行的 C# WinForms 应用程序。它有一个计时器。当 OnTimedEvent 触发时,我检查我是否对要上传的文件具有独占访问权限(以确保它已完成写入磁盘),然后尝试上传。如果上传成功,我将文件移动到存档文件夹,否则我将其留在那里并等待下一个计时器事件。连接到 Internet 时我没有问题,但是当我没有进行测试并且我的上传失败时,第二个 OnTimedEvent 在检查同一个文件是否准备好(再次)时出现异常。我得到了:
Error message: ***Sharing violation on path 'path'
***HResult: ***-2147024864
检查文件是否准备好的方法:
public static bool IsFileReady(string filename)
{
// If the file can be opened for exclusive access it means that the file
// is no longer locked by another process.
try
{
var inputStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None);
bool test = inputStream.Length > 0;
inputStream.Close();
inputStream.Dispose();
return test;
}
catch (Exception e)
{
//log
throw e;
}
}
这是在 OntimedEvent 上执行的:
var csvFiles = from f in di.GetFiles()
where f.Extension == ".csv"
select f; //get csv files in upload folder
foreach (var file in csvFiles)
{
if (IsFileReady(file.FullName)) //check that file is done writing before trying to move.
{
bool IsUploadSuccess = await WritingCSVFileToS3Async(file);//.Wait(); //upload file to S3
if (IsUploadSuccess)
{
File.Move(file.FullName, archivePath + file.Name); //move to completed folder if upload successful. else, leave there for next upload attempt
}
}
}
据我所知,当第二个事件触发时,我的第一个 FileStream (File.Open) 似乎仍然锁定了文件。但是,我已将 .Close() 和 .Dispose() 添加到 IsFileReady 方法,但这似乎不起作用。
任何帮助将不胜感激!
编辑:下面是 WritingCSVFileToS3Async 方法。
static async Task<bool> WritingCSVFileToS3Async(FileInfo file)
{
try
{
client = new AmazonS3Client(bucketRegion);
// Put the object-set ContentType and add metadata.
var putRequest = new PutObjectRequest
{
BucketName = bucketName,
Key = file.Name,
FilePath = file.FullName ,
ContentType = "text/csv"
};
//putRequest.Metadata.Add("x-amz-meta-title", "someTitle"); //don't need meta data at this time
PutObjectResponse response = await client.PutObjectAsync(putRequest);
if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
return true;
else
return false;
}
catch (AmazonS3Exception e)
{
ErrorLogging.LogErrorToFile(e);
return false;
}
catch (Exception e)
{
ErrorLogging.LogErrorToFile(e);
return false;
}
另外,我在 Windows 上运行了相同的应用程序,并且遇到了类似的异常:
The process cannot access the file 'path' because it is being used by another process.
【问题讨论】:
-
打开文件后关闭文件前是否有异常抛出?您可能应该将文件操作包装在
using块中。 -
旁注:不要手动调用 Close/Dispose,请使用
using语句 (docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…)。除此之外,我们无法判断问题出在哪里,因为问题中的代码没有提示可能的问题场景...... :(可能是您在其他方法中的代码打开了同一个文件并且确实没有正确关闭它(很可能对我来说,考虑到您在此处手动添加关闭/处置的“hack-ish”尝试)。可能是系统上的其他一些事情/进程干扰了您的程序;不知道......跨度> -
我本来有一个using语句,但还是有问题,所以我尝试手动调用它们。这是打开文件的唯一方法。它首先被复制并重命名为“上传”目录。我可以在第一个计时器事件中访问它。这是我第二次无法访问它。在测试期间,没有其他方法在两个计时器事件之间触发。我想知道它是否与非本机 linux 文件 I/O 无关,并且第一次打开文件的进程没有以某种方式清理。
-
嗯,你说上传失败时会发生这种情况,所以我认为
WritingCSVFileToS3Async没有正确处理文件。请张贴其代码 -
旁注:当您发布问题时,请留下来回答 cmets,如果您发布问题并且仅在 3 小时后回来,您希望如何获得帮助?看问题的人早就走了,现在网上的人可能不会看你的问题,因为它太旧了
标签: c# file file-io timer mono