다른 레코드와 관련된 일련의 9 가지 워크 플로를 제공하는 회사의 문서 관리 시스템을 작성하라는 요청을 받았습니다. 워크 플로우 중에는 "파일"또는 레코드에 문서를 추가하고 비즈니스 규칙에 따라 공개 웹 사이트에 이러한 문서의 하위 집합을 게시하는 작업이 있습니다.파일 실행 시간이 오래 걸리고 실행 시간이 초과 됨
문서는 거의 예외없이 PDF 형식으로 제공되며, 일반적으로 한 문서에 대해 20 개 미만의 문서가 한 번에 처리됩니다.
웹 응용 프로그램으로 구축하려는 주된 이유는 원격 사이트에서 잠재적으로 느린 연결 속도를 통해 위치간에 위아래로 복사를 시도하는 대신 데이터 센터 및 고속 스위치에 파일을 보관하는 것이 었습니다.
시스템은 문서의 큰 시리즈까지 완벽하게 일했다(114 개 PDF 문서를 완전히 크기 3백29메가바이트가)의 방식 약 95 %를 초과되었습니다.
코드는 (IncomingDocuments 유형 목록 <의에서는 FileInfo >입니다) - 유틸리티 방법으로
List<string> filesSuccessfullyAdded = new List<string>();
foreach (FileInfo incomingFile in IncomingDocuments)
{
FileOperations.AddDocument(incomingFile, false, ApplicationCode, (targetDirectoryPath.EndsWith(@"\") ? targetDirectoryPath : targetDirectoryPath + @"\"));
FileInfo copiedDocument = new FileInfo(Path.Combine(targetDirectoryPath, incomingFile.Name));
if (copiedDocument.Exists && copiedDocument.Length == incomingFile.Length && copiedDocument.LastWriteTime == incomingFile.LastWriteTime)
{
filesSuccessfullyAdded.Add(copiedDocument.Name);
}
}
if (filesSuccessfullyAdded.Any())
{
SetupConfirmationLiteral.Text += "<p class='info'>The following files have been successfully added to the application file-</p>";
XDocument successfullyAddedList = new XDocument(
new XElement("ul", new XAttribute("class", "documentList")));
foreach (string successfulFile in filesSuccessfullyAdded)
{
successfullyAddedList.Root.Add(new XElement("li", successfulFile));
}
SetupConfirmationLiteral.Text += successfullyAddedList.ToString();
}
var notSuccessfullyAdded = from FileInfo incomingDocument in IncomingDocuments
where !filesSuccessfullyAdded.Contains(incomingDocument.Name)
orderby incomingDocument.Name ascending
select incomingDocument.Name;
if (notSuccessfullyAdded.Any())
{
SetupConfirmationLiteral.Text += "<p class='alert'>The following files have <strong>not</strong> been successfully added to the application file-</p>";
XDocument notAddedList = new XDocument(
new XElement("ul", new XAttribute("class", "documentList")));
foreach (string notAdded in notSuccessfullyAdded)
{
notAddedList.Root.Add(new XElement("li", notAdded));
}
SetupConfirmationLiteral.Text += notAddedList.ToString();
SetupConfirmationLiteral.Text += "<p>A file of the same name may already exist in the target location.</p>";
}
public static void AddDocument(FileInfo sourceFile, bool appendName, string applicationCode, string targetPath)
{
try
{
DirectoryInfo targetDirectory = new DirectoryInfo(targetPath);
if (targetDirectory.Exists)
{
string targetFileName = (appendName ? sourceFile.Name.Insert(sourceFile.Name.IndexOf(sourceFile.Extension, StringComparison.Ordinal), " UPDATED") : sourceFile.Name);
if (targetDirectory.GetFiles(targetFileName).Any())
{
//Do not throw an exception if the file already exists. Silently return. If the file exists and matches both last modified and size it won't be reported, and can be archived as normal,
//otherwise it should be reported to user in the calling method.
return;
}
string targetFileUnc = Path.Combine(targetPath, targetFileName);
sourceFile.CopyTo(targetFileUnc, overwrite: false);
Logging.FileLogEntry(username: (HttpContext.Current.User.Identity.IsAuthenticated ? HttpContext.Current.User.Identity.Name : "Unknown User"), eventType: LogEventType.AddedDocument,
applicationCode: applicationCode, document: sourceFile.Name, uncPath: targetFileUnc);
}
else
{
throw new PdmsException("Target directory does not exist");
}
}
catch (UnauthorizedAccessException ex)
{
throw new PdmsException("Access was denied to the target directory. Contact the Service Desk.", ex);
}
catch (PathTooLongException)
{
throw new PdmsException(string.Format("Cannot add document {0} to the Site File directory for Application {1} - the combined path is too long. Use the Add Documents workflow to re-add documents to this Site File after renaming {0} to a shorter name.", sourceFile.Name, applicationCode));
}
catch (FileNotFoundException ex)
{
throw new PdmsException("The incoming file was not found. It may have already been added to the application file.", ex);
}
catch (DirectoryNotFoundException ex)
{
throw new PdmsException("The source or the target directory were not found. The document(s) may have already been added to the application file.", ex);
}
catch (IOException ex)
{
throw new PdmsException("Error adding files - file(s) may be locked or there may be server or network problem preventing the copy. Contact the Service Desk.", ex);
}
}
외하면 실제 사본 및 감사를 수행합니다. PdmsException은 사용자에게 유용한 오류 메시지를 표시하기 위해 사용하는 특정 예외 클래스 일 뿐이므로 가능하면 문제를 해결하거나 오류에 대해 이해할 수있는 이유를 제시 할 수 있습니다.
ExecutionTimeout 속성 (http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.executiontimeout.aspx)을 기본 값 인 110 초 (최대 300 초)를 단순히 늘릴 수 있음을 알고 있습니다.이 경우 아마도이 시간 초과가 발생하지 않을 수도 있지만 사용자가 수천 개의 문서를 추가하거나 게시 할 수 있습니다. 이 솔루션은 문제를 해결하는 것보다는 단순히 지연시키는 것만으로 확장되지 않습니다.
Visual Studio 2010과 함께 .NET 4를 사용하고 있습니다. 따라서 async를 사용하여 타사 구현을 사용해야하고 AsyncBridge (https://nuget.org/packages/AsyncBridge)를 기다려야합니다. 문서를 소싱하고 진행을 업데이트하려면 ajax를 사용하십시오. . Microsoft가 제공 한 비동기 타겟팅 팩을 사용하기 위해 Visual Studio 2012 또는 XP보다 최신 버전의 Windows에 액세스 할 수 없습니다.
이러한 제약 조건을 고려할 때 제한 시간을 피하기 위해 이러한 문서를 위/일괄 처리하고 각 일괄 처리가 추가 될 때 사용자에게 피드백을 제공하는 방법이 있습니까? 구현하기가 간단하다면 F #을 탐험 할 수 있습니다. 또는 Visual Studio 2012에 대해이 케이스를 탄원해야합니까?
궁금한 점이 있습니다. 조직에서 'SharePoint'를 사용하거나 구현할 수 없습니까? 당신이 'Wheel'을 재발 명하도록 요청받은 것처럼 들린다. – MethodMan
질문을 downvoting하는 사람들은 왜 설명 할 수 있습니까? 나는 약간의 추론과 함께 그것을 턱에 가져갈 것보다 더 기쁩니다. – pwdst
타사 제품과 통합해야하므로 Sharepoint는이 시나리오에서 옵션이 아닙니다. – pwdst