0

私は MVC と .NET にかなり慣れていませんが、3 日間立ち往生している最初の問題に遭遇しました。長い投稿をお詫び申し上げます。

私が取り組んでいるプロジェクトの一部では、アプリケーションがデータをインポートできるように、ユーザーが XLS または XLSX ファイルを選択してアップロードできる必要があります。アップロードされるファイルには、20,000 行以上のデータが含まれる可能性があります。

5000、10000、および 20000 行のテスト ファイルがあります。(Visual Studio 2010 を使用して) ローカル コンピューターでアプリを実行すると、これらのファイルはすべてネットワーク共有に保存され、正常に処理されます。エラーなし。ただし、アプリを開発サーバーにデプロイすると、5 分後に、別のプロセスで使用されているため、10k および 20k ファイルにアクセスできないというエラーが表示されます。

エラー メッセージ: 別のプロセスで使用されているため、プロセスはファイルにアクセスできません。

スタックトレース:

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy) 
at System.IO.FileStream..ctor(String path, FileMode mode) 
at System.Web.HttpPostedFile.SaveAs(String filename) 
at System.Web.HttpPostedFileWrapper.SaveAs(String filename) 
at edtStar.Controllers.TableController.Import(HttpPostedFileBase UploadFile, FormCollection collection) in <removed this part of the path>\TableController.cs:line 392

10000 行のファイルのサイズは 304 KB で、web.config で次のように長さ制限を設定しています。

<httpRuntime 
  maxRequestLength="4096"
  requestLengthDiskThreshold="1024"/>

5 分ほど特別なことは何も見つかりませんが、アップロードを開始してから 5 分後には常にエラーが返されます。

Chrome と IE で試してみました。どちらも localhost 経由で動作し、dotnet アプリ サーバー経由では動作しません。

スタック トレースは、SaveAs() メソッドで爆発していると言っていますが、ネットワーク共有の場所にファイルがあり、サイズが一致していることがわかります。

ファイルを保存したら、それを読み取ってデータを新しいビューに戻す必要があります。ビューにデータを返す前に、かなりの量の処理が行われています。ここで 5 分以上待つことが予想されます。ファイルの読み取りが完了したら、接続を閉じてネットワーク共有からファイルを削除します。私も例外を受け取った直後にファイルが削除されます。各アップロードを開始するときにファイルが存在しません。

このアプリケーションはまだ開発中であるため、現在このアプリケーションを使用しているのは私だけです。私がテストを行っている間、他の誰かがネットワーク共有に保存されたコピーにアクセスしているとは思えません。この問題は一貫して再現できますが、なぜ発生するのかわかりません。

誰かがこのようなものを見たことがありますか、それとも私に何か提案がありますか? アプリサーバーのどこかに設定があると思いますが、特定できませんでした。

ありがとう!

編集:

ファイルのアップロードを処理するコードは次のとおりです。

// Validate, save, and read the selected file.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Import(HttpPostedFileBase UploadFile, FormCollection collection)
{
  // Do some initial file validation - removed

  string filePath = Path.Combine(EDTConstants.NETWORK_SHARE_PATH, Path.GetFileName(UploadFile.FileName));

  try
  {
    // Do some validation on the file that was uploaded.
    if (UploadFile == null)
    {
      // return an error here - there was no file selected.
    }

    if (UploadFile.ContentLength == 0)
    {
      // return an error here - the file is empty.
    }

    if (!filePath.ToUpper().EndsWith("XLS") && !filePath.ToUpper().EndsWith("XLSX"))
    {
      // return an error here - the file extension is not supported.
    }

    // Things are good so far.  Save the file so we can read from it.
    UploadFile.SaveAs(filePath);
    DataSet fileDS = new DataSet();
    string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=YES;\"";
    using (OleDbConnection conn = new OleDbConnection(connString))
    {
      conn.Open();
      using (DataTable dtExcel = conn.GetSchema("Tables"))
      {
        // ... a bunch of code removed ...
      }
      conn.Close();
    }

    CloseFile(filePath);
  }
  catch (Exception e)
  {
    // Unexpected error
    EDTUtils.LogErrorMessage(EDTConstants.TABLE_IMPORT, User.Identity.Name, e);
    ViewData[EDTConstants.SSN_VD_ERROR_MSG] = EDTConstants.EM_UNEXPECTED + System.Environment.NewLine + e.Message;
    ViewData[EDTConstants.VIEWDATA_FILE] = UploadFile.FileName;
    CloseFile(filePath);
    return View(tab);
  }

// Closes a file - logs errors but does not throw any exceptions.
private void CloseFile(string filePath)
{
  try
  {
    System.IO.File.Delete(filePath);
  }
  catch (IOException ioe)
  {
    EDTUtils.LogErrorMessage(EDTConstants.TABLE_IMPORT, User.Identity.Name, ioe);
  }
}

SaveAs() を実行するときに 1 回、次に Delete を実行するときに同じエラーがログに記録されます。奇妙なことに、ファイルは消えてしまいます。アプリサーバーには、このプロセス中に何かをしようとしている別のスレッドがあり、ローカルホストでは発生しないようです。

編集

executionTimeout 値を変更した後、Chrome が 5 分後に「アップロード中 79%...」と表示し、ネットワーク共有でファイルが消えて再び表示され、1、2 分後に Chrome がそのページを表示したことに気付きました。 「エラーコード: ERR_INVALID_RESPONSE」で利用できませんでした。ファイルはまだネットワーク共有から削除されていません。IE では、5 分後にもう一度アプリにログインするように求められます。

4

1 に答える 1