C# 进程无法访问文件';XXX和x27;因为它正被另一个进程使用,如果我再次发送

C# 进程无法访问文件';XXX和x27;因为它正被另一个进程使用,如果我再次发送,c#,asp.net-mvc-5,docusignapi,filestream,C#,Asp.net Mvc 5,Docusignapi,Filestream,当我在开发模式下重新加载页面以创建第二封邮件并将其与文件一起发送时,会出现此错误,即使第二个变量“eqc”为“true”,它也会落在第一个变量“emc”中,并且在prod中仍会出现此错误,就好像文件仍然打开一样,我不知道在哪里,我知道我必须关闭“路径”,但是你能告诉我在哪里吗?这是我的代码: public ActionResult EditPersonalityTest([Bind(Include = "ID,EnglishProefficiencyBefore")] Recipient rec

当我在开发模式下重新加载页面以创建第二封邮件并将其与文件一起发送时,会出现此错误,即使第二个变量“eqc”为“true”,它也会落在第一个变量“emc”中,并且在prod中仍会出现此错误,就好像文件仍然打开一样,我不知道在哪里,我知道我必须关闭“路径”,但是你能告诉我在哪里吗?这是我的代码:

public ActionResult EditPersonalityTest([Bind(Include = "ID,EnglishProefficiencyBefore")] Recipient recipient, CohortSubscriptions cohortSubscriptions)
        {

            var property = db.CohortSubscriptions.Where(x => x.ID == cohortSubscriptions.ID).FirstOrDefault();

            property.EnglishProefficiencyBefore = cohortSubscriptions.EnglishProefficiencyBefore;


            db.Entry(property).State = EntityState.Modified;
            db.SaveChanges();

            Registrations registration = db.Registrations.Where(x => x.ID == property.RegistrationId).FirstOrDefault();
            bool isEnglish = IsEnglishLocale(registration);
            recipient.Name = registration.FirstName + " " + registration.LastName;
            recipient.Email = registration.Email;

            Recipient recipientModel = new Recipient();
            string directorypath = Server.MapPath("~/App_Data/" + "Files/");
            if (!Directory.Exists(directorypath))
            {
                Directory.CreateDirectory(directorypath);
            }
            byte[] data;

            bool englishMontreal = isEnglish  && registration.PreferredCampus == "Montreal";
            bool englishQuebec = isEnglish  && registration.PreferredCampus == "Québec";
            bool frenchMontreal = isEnglish == false && registration.PreferredCampus == "Montreal";
            bool frenchQuebec = isEnglish == false && registration.PreferredCampus == "Québec";

            //English Montreal First Contract
            var emc = new FileStream(Server.MapPath("~/Documents/Contrats Montreal English.pdf"), FileMode.Open);
            //English Quebec First Contract
            var eqc = new FileStream(Server.MapPath("~/Documents/Contrats Quebec English.pdf"), FileMode.Open);
            //English Secon Contract
            //var esc = new FileStream(Server.MapPath("~/Documents/CodeBoxx Technology Corporation English.pdf"), FileMode.Open);
            //French Montreal First Contract
            var fmc = new FileStream(Server.MapPath("~/Documents/Contrats Montreal French.pdf"), FileMode.Open);
            //French Quebec First Contract
            var fqc = new FileStream(Server.MapPath("~/Documents/Contrats Quebec French.pdf"), FileMode.Open);
            //French Second Contract
            //var fsc = new FileStream(Server.MapPath("~/Documents/CodeBoxx Technology Corporation Contrat.pdf"), FileMode.Open);


            if (englishMontreal == true)
            {


                //First contract
                using (Stream inputStream = emc)
                {
                    MemoryStream memoryStream = inputStream as MemoryStream;
                    if (memoryStream == null)
                    {
                        memoryStream = new MemoryStream();
                        inputStream.CopyTo(memoryStream);
                    }
                    data = memoryStream.ToArray();
                }
                serverpath = directorypath + recipient.Name.Trim() + ".pdf";
                System.IO.File.WriteAllBytes(serverpath, data);
                docusignContract(serverpath, recipient.Name, recipient.Email);
            }

            if (englishQuebec == true)
            {


                using (Stream inputStream = eqc)
                {
                    MemoryStream memoryStream = inputStream as MemoryStream;
                    if (memoryStream == null)
                    {
                        memoryStream = new MemoryStream();
                        inputStream.CopyTo(memoryStream);
                    }
                    data = memoryStream.ToArray();
                }
                serverpath = directorypath + recipient.Name.Trim() + ".pdf";
                System.IO.File.WriteAllBytes(serverpath, data);
                docusignContract(serverpath, recipient.Name, recipient.Email);


            }

            if (frenchMontreal == true)
            {
                using (Stream inputStream = fmc)
                {
                    MemoryStream memoryStream = inputStream as MemoryStream;
                    if (memoryStream == null)
                    {
                        memoryStream = new MemoryStream();
                        inputStream.CopyTo(memoryStream);
                    }
                    data = memoryStream.ToArray();
                }
                serverpath = directorypath + recipient.Name.Trim() + ".pdf";
                System.IO.File.WriteAllBytes(serverpath, data);
                docusignContract(serverpath, recipient.Name, recipient.Email);


            }

            if (frenchQuebec == true)
            {
                using (Stream inputStream = fqc)
                {
                    MemoryStream memoryStream = inputStream as MemoryStream;
                    if (memoryStream == null)
                    {
                        memoryStream = new MemoryStream();
                        inputStream.CopyTo(memoryStream);
                    }
                    data = memoryStream.ToArray();
                }
                serverpath = directorypath + recipient.Name.Trim() + ".pdf";
                System.IO.File.WriteAllBytes(serverpath, data);
                docusignContract(serverpath, recipient.Name, recipient.Email);

            }
            System.IO.File.Delete(serverpath);  //my supposition
            return View("ConfirmEditSubscriptions");

        }

到现在为止,你可能已经发现了这个问题,但以下是我的发现

有几个FileStream open从未使用过。每次调用函数时,流
emc
eqc
fmc
fqc
都是打开的,只有1个被处理,这就是为什么在第二次调用时,另一个进程仍在使用某些文件的原因

为了便于调试,我总是开始删除代码重复,基本上,除了
输入流
源代码外,您的函数具有4倍于相同代码块的99%相同的代码块

从您的代码中,我还注意到,此代码块将始终返回
null inputStream

。。。
使用(Stream inputStream=eqc){
MemoryStream MemoryStream=inputStream作为MemoryStream;//eqc是一个文件流,它不能作为MemoryStream强制转换,它始终为空
...
解决方案

这是您函数的一个小重构。我删除了
未使用的变量
,并将变量定义移到更接近用法的位置。您还会注意到,没有
if()
语句剩余(
Directory.CreateDirectory()
如果目录已经存在,则不会引发异常)。
更好代码的我的规则:删除尽可能多的代码,这将减少代码路径和出错的机会

public ActionResult EditPersonalityTest([Bind(Include=“ID,englishproeficiencyBefore”)]收件人收件人,共同订阅共同订阅)
{
var property=db.coortsubscriptions.Where(x=>x.ID==coortsubscriptions.ID).FirstOrDefault();
property.EnglishProefficiencyBefore=共同订阅。EnglishProefficiencyBefore;
db.Entry(property).State=EntityState.Modified;
db.SaveChanges();
Registrations registration=db.Registrations.Where(x=>x.ID==property.RegistrationId).FirstOrDefault();
recipient.Name=registration.FirstName+“”+registration.LastName;
recipient.Email=registration.Email;
//将校园名称映射到FileNamePart的数组
var campusNameMap=new[]{
新{PreferredCampus=“Montreal”,FileNamePart=“Montreal”},
新{PreferredCampus=“魁北克”,FileNamePart=“魁北克”},
};
//基于isEnglish和registration.PreferredCampus生成pdfDocumentPath
字符串campusFileNamePart=campusNameMap.Single(校园=>campus.PreferredCampus==registration.PreferredCampus).FileNamePart;
string languageFileNamePart=IsEnglishLocale(注册)?“英语”:“法语”;
//仅使用1个inputStream
使用(FileStream inputStream=newfilestream(Server.MapPath($“~/Documents/contracts{campusFileNamePart}{languageFileNamePart}.pdf”)、FileMode.Open)
{
MemoryStream MemoryStream=新的MemoryStream();
inputStream.CopyTo(memoryStream);
字符串directorypath=Server.MapPath(“~/App\u Data/Files/”);
CreateDirectory(directorypath);
字符串serverpath=$“{directorypath}{recipient.Name.Trim()}.pdf”;
System.IO.File.writealBytes(serverpath,memoryStream.ToArray());
docusignContract(serverpath,recipient.Name,recipient.Email);
System.IO.File.Delete(serverpath);
}
返回视图(“确认订阅”);
}

我希望它对您有用。

您现在可能已经发现了问题,但以下是我的发现

有几个从未使用过的FileStream open。每次调用函数时,Streams
emc
eqc
fmc
fqc
都是打开的,只有1个文件被处理,这就是为什么在第二次调用时,另一个进程仍在使用某些文件的原因

为了便于调试,我总是开始删除代码重复,基本上,除了
输入流
源代码外,您的函数具有4倍于相同代码块的99%相同的代码块

从您的代码中,我还注意到,此代码块将始终返回
null inputStream

。。。
使用(Stream inputStream=eqc){
MemoryStream MemoryStream=inputStream作为MemoryStream;//eqc是一个文件流,它不能作为MemoryStream强制转换,它始终为空
...
解决方案

这是您函数的一个小重构。我删除了
未使用的变量
,并将变量定义移到更接近用法的位置。您还会注意到,没有
if()
语句剩余(
Directory.CreateDirectory()
如果目录已经存在,则不会引发异常)。
更好代码的我的规则:删除尽可能多的代码,这将减少代码路径和出错的机会

public ActionResult EditPersonalityTest([Bind(Include=“ID,englishproeficiencyBefore”)]收件人收件人,共同订阅共同订阅)
{
var property=db.coortsubscriptions.Where(x=>x.ID==coortsubscriptions.ID).FirstOrDefault();
property.EnglishProefficiencyBefore=共同订阅。EnglishProefficiencyBefore;
db.Entry(property).State=EntityState.Modified;
db.SaveChanges();
Registrations registration=db.Registrations.Where(x=>x.ID==property.RegistrationId).FirstOrDefault();
recipient.Name=registration.FirstName+“”+registration.LastName;
recipient.Email=registration.Email;
//将校园名称映射到F的数组