打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Asp.net异步文件读写并发处理总结

运行场景

系统在用户打开下载页面的时候异步请求,根据数据动态生成一个Word文件,并返回给页面文件的大小显示在页面上,用户在生成后可以点击下载获取生成的Word文件,不希望数据有超过5分钟的延迟。

遇到的问题

一开始很简单的写了几句代码,在本地测试通过。省去业务逻辑的代码如下

生成Word:

protected int CreateWord()

{

string strFilePath = @"D:\NewWord.docx";

 ProjectWord word = new ProjectWord();

word.Save(strFilePath);

System.IO.FileInfo file = new System.IO.FileInfo(strFilePath);

return file.Length;

}

下载Word:

Response.ContentType = "application/x-zip-compressed";

Response.AddHeader("Content-Disposition", "attachment;filename=" + Path.GetFileName(strFilePath));

Response.TransmitFile(strFilePath);

Response.Flush();

Response.End();

 

上传到服务器的时候,大量的操作就出问题了。在word.Save的时候出现了IO读写错误,想了想是文件被用户下载的时候,给占用的,读写不能同时操作,怎么办呢?

方案一

生成Word的代码:

protected int CreateWord()

{

string strFilePath = @"D:\NewWord.docx";

 

System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() =>

{

ProjectWord word = new ProjectWord();

int i = 0;

while (i < 10)

{

try

{

word.Save(strFilePath);

}

catch

{

System.Threading.Thread.Sleep(1000);

i++;

}

}

}));

t.Start();

System.IO.FileInfo file = new System.IO.FileInfo(strFilePath);

return file.Length;

}

下载Word代码不变。

网站不在报错了,用户也能正常下载了文件,但下载出来的文件有时候不是及时的,原因太简单了,保存10次都没成功的话,就不保存了,而且并发量大的时候是几乎不会成功的。只适合小并发量的情况下使用该方法,小并发量我也不推荐,虽然我使用了这个方法顶了几个小时。

方案二:

生成Word的代码:

protected int CreateWord()

{

string strFilePath = @"D:\NewWord.docx";

lock (brCreaterAddressLock)

{

System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() =>

{

brCreaterAddressLock.AddParticipant();

ProjectWord word = new ProjectWord();

int i = 0;

while (i <= 10)

{

try

{

word.Save(strFilePath); }

catch

{

}

finally

{

brCreaterAddressLock.RemoveParticipant();

}

}

}));

t.Start();

}

System.IO.FileInfo file = new System.IO.FileInfo(strFilePath);

return file.Length;

}

public static System.Threading.Barrier brCreaterAddressLock = new System.Threading.Barrier(0);

 

下载Word的代码:

Handler.brCreaterAddressLock.AddParticipant();

Handler.brCreaterAddressLock.SignalAndWait();

Response.ContentType = "application/x-zip-compressed";

Response.AddHeader("Content-Disposition", "attachment;filename=" + Path.GetFileName(strFilePath));

Response.TransmitFile(strFilePath);

Response.Flush();

Response.End();

该方案运行良好,但下载的响应速度有点慢,在生成的时候,下载的线程需要等生成的线程结束后才能运行。这样对用户的来说不太好,虽然word的生成也只是几秒钟,而且是异步生成文件,页面上有个转圈圈的图片给用户看。

方案三

生成Word的代码:

protected int CreateWord()

{

if (brCreaterAddressLock.ParticipantCount == 0)

{

lock (brCreaterAddressLock)

{

System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() =>

{

brCreaterAddressLock.AddParticipant();

ProjectWord word = new ProjectWord();

int i = 0;

while (i <= 10)

{

try

{

word.Save(@"D:\NewWord.docx");

}

catch

{

}

finally

{

brCreaterAddressLock.RemoveParticipant();

isCreatingAddress = false;

}

}

}));

t.Start();

}

}

 

System.IO.FileInfo file = new System.IO.FileInfo(strFilePath);

 

return file.Length;

 

 

}

public static System.Threading.Barrier brCreaterAddressLock = new System.Threading.Barrier(0);

下载Word的代码:

Handler.brCreaterAddressLock.AddParticipant();

Handler.brCreaterAddressLock.SignalAndWait();

Handler.brCreaterAddressLock.RemoveParticipant();//要注意这句,SignalAndWait()不会帮你移除一个参与者,如果没这句的话,在生成的时候 if (brCreaterAddressLock.ParticipantCount == 0)这句就只会运行一次

Response.ContentType = "application/x-zip-compressed";

Response.AddHeader("Content-Disposition", "attachment;filename=" + Path.GetFileName(strFilePath));

Response.TransmitFile(strFilePath);

Response.Flush();

Response.End();

这样的话,用户在文件生成中的时候就会给他直接旧版文件的大小,加快了异步的响应速度,提高了用户体验。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
更有效的文件下载功能
C# 从服务器下载文件代码
C# Aspose.Cells.dll Excel操作总结
【新機能】AWS LambdaがPythonに対応しました #reinvent | Developers.IO
Extjs 文件上传功能
ASP.NET上传和下载文件的代码(转载)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服