0

私は現在、FTPの詳細を受け入れ、ファイルリストを取得し、ユーザーがファイルをダウンロードできるようにするコードを記述しようとしています。

これはすべて正常に機能しますが、ファイルのダウンロードが完了するのを待ってから何かを実行する必要があります。非同期コントローラーを使用しているのは、これがこの種のことを支援するためのものだと思ったからです。

以下の私のコードの選択を参照してください、私は関連しないすべてのコードを省略しました:

  [HttpPost]
    public ActionResult FtpAsync(Downloads model)
    {
        var ftpAddress = model.Url;
        if (!ftpAddress.StartsWith("ftp://"))
            ftpAddress = String.Concat("ftp://", ftpAddress);

        var serverPath = Server.MapPath(ThumbnailSupport.CreateBaseVirtualPathForClient(StandardFileLinks.DropBoxLocation,
                                                                        _website.Client));

        if (!Directory.Exists(serverPath))
            Directory.CreateDirectory(serverPath);

        foreach (string file in model.SelectedFiles)
        {

            var webClient = new WebClient();

            AsyncManager.OutstandingOperations.Increment();

            AsyncManager.Parameters["FilesToDownload"] = model.SelectedFiles;
            webClient.Credentials = new NetworkCredential(model.Username, model.Password);

            webClient.DownloadFileAsync(new Uri(ftpAddress + "/" + file), serverPath + "\\" + file);
            AsyncManager.OutstandingOperations.Decrement();
        }

        return RedirectToAction("Transfer");

    }


    public ActionResult FtpCompleted(Downloads model)
    {
        return RedirectToAction("Complete");
    }

    public ActionResult Transfer()
    {
        return PartialView();
    }

FtpCompletedアクションを完全に正常に実行しますが、問題は、これが潜在的にGBの情報のファイル転送を処理することを意図していることです。ファイルがダウンロードされるのを待つ間、ユーザーが回転するディスクを見ながら座ってほしくない。したがって、転送アクションにリダイレクトしようとした理由は、このアクションは、転送に時間がかかる可能性があることを通知するメッセージを表示するだけで、転送が完了すると通知されます。ただし、このアクションが実際に呼び出されることはありません。デバッグでコードをステップ実行すると、コードが呼び出されますが、FireBugによると、メッセージが表示されず、ブラウザーに到達しません。

私は愚かなことをしていますか、それともこれを行うことは不可能ですか?

ここでグーグルや他の投稿を閲覧した後、私は完全に立ち往生しているので、人々がここで提供できるどんな援助にも感謝します。はるかに経験豊富なコーダーである私の上司でさえ、これをどのように処理するかがわかりません。

前もって感謝します、

ガズ

4

1 に答える 1

1

ドキュメントで説明されているように、非同期コントローラーアクションは2つの方法で構成されています。

  1. voidを返し、Async接尾辞とアクション名の接頭辞を持つメソッド
  2. ActionResultを返し、Completed接尾辞とアクション名の接頭辞を持つメソッド

最初のメソッドは非同期操作をトリガーし、すぐに戻ります。2番目のメソッドは、操作全体が完了すると呼び出されます。

したがって、正しいアクションシグネチャは次のとおりです。

[HttpPost]
public void FtpAsync(Downloads model)
{
    ...
}

public ActionResult FtpCompleted(Downloads model)
{
    return Content("Complete");
}    

ここで、操作全体でブラウザーをフリーズしたくない場合は、AJAXを使用して最初のコントローラーアクションを呼び出す必要があります。非同期コントローラーは、HTTPプロトコルに関して何も変更しません。クライアントの観点からは、それはまったく同じです。標準のコントローラーアクションとの唯一の違いは、操作全体でワーカースレッドを危険にさらさないことです。現在、によって使用されるOSアーティファクトであるIOCP(IO /完了ポート)に依存しています。WebClient。IOを集中的に使用する操作を開始すると、IOCPポートが作成され、コントローラーアクションによってスレッドがASP.NETスレッドプールにすぐに返されます。その後、操作は数時間続く可能性があり、IOCPが完了すると、スレッドプールからプールが引き出され、このスレッドでCompletedアクションが呼び出されます。したがって、スレッドに関しては非常に効果的です。ただし、実行の合計時間は、標準のコントローラーアクションを使用した場合とまったく同じです。多くの人は、非同期コントローラーは非同期と呼ばれるため、クライアントの観点から非同期で実行されると考えています。それは間違った印象です。非同期アクションによって、操作が奇跡的に速くなることはありません。HTTPプロトコルが機能する方法であるため、クライアントの観点からはまだ完全に同期しています。

したがって、2つの可能性があります。

  • AJAXを使用してコントローラーアクションを呼び出し、ブラウザーのブロックを回避します。
  • クライアントに通知するのはサーバーであるCOMET/PUSHテクノロジーを使用します。たとえば、HTML5には、それを実現するために使用できるWebSocket標準があります。.NETの世界では、 SignalRはこのプッシュテクノロジーをカプセル化する優れたフレームワークです。

本当に効果的なソリューションが必要な場合は、2番目のアプローチをお勧めします。

于 2012-07-04T15:50:54.457 に答える