0

UI を保持する大規模なデータ セットがあるため、バックグラウンド呼び出しを作成してローカル リポジトリを埋め、他のコントロールをすぐに UI に表示し、応答を受け取ったときに非同期呼び出しの結果を読み込むことを考えました。

役立つチュートリアルを見つけましたが、コントロールが表示される前に、すべての結果が読み込まれるまで待つ必要があります。

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

コードが更新されました

Services というフォルダーを作成し、そのフォルダーに FacilitiesService.cs を作成しました。以下を参照してください。

public class FacilitiesService
{
    internal async Task<List<Facility>> GetFacilitiesBySourceDbAsync(string sourceDb)
    {
        var fac = new Facility();

        var con = Connect(); // Omitted

        try
        {
            con.Open();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: GetFacilityBySourceDb " + ex.Message);
        }

        try
        {
            OracleDataReader reader = null;
            // Requestor
            var cmd = new OracleCommand("SELECT FACILITY, FACILITY_ID FROM MyTable where (source_db = '" + sourceDb + "')", con);

            reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                fac.Add(new Facility()
                {
                    FacilityName = reader["FACILITY"].ToString(),
                    FacilityId = reader["FACILITY_ID"].ToString()
                });
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            con.Close();
            con.Dispose();
        }

        return fac;
    }
}

次に、私の HomeController.cs には次のものがあります。

public class HomeController
{
    public async Task<List<Facility>> FacilitiesAsync()
    {
        ViewBag.SyncOrAsync = "Asynchronous";
        var service = new FacilitiesService();

        this._facilities = new List<Facility>();

        var facilities = await service.GetFacilitiesBySourceDbAsync("TEST");

        foreach (var item in facilities)
        {
            Facility fac = new Facility()
            {
                FacilityName = item.FacilityName,
                FacilityId = item.FacilityId
            };

            _facilities.Add(fac);
        }

        return _facilities;
    }
}

これは私の施設(モデル)クラスです:

public class Facility : List<Facility>
{
    [Required]
    [Display(Name = "Facility")]
    public string FacilityName { get; set; }
    public string FacilityId { get; set; }

    public Facility()
    {
        // Default Constructor
    }

    public Facility(string facilityName, string facilityId)
    {
        this.FacilityName = facilityName;
        this.FacilityId = facilityId;
    }
}

ユーザーが "tags" の ID を持つ tetbox/input コントロールからタブを離したときに、About.cshtml ページの関数呼び出しからコード ビハインドで FacilitiesAsync メソッドを開始するために Ajax 呼び出しを使用しています。これを何かに切り替えることができます。後でですが、コード ビハインドをステップ実行するとデータが返され、beforeSend 関数と complete 関数の両方でアラートが発生することがわかります。

<script type="text/javascript">
$(function () {
    var availableTags = [
    // Neeed data from function call to populate this list
    ];
    $("#tags").autocomplete({
        source: availableTags
    });
    $("#tags").focusout(function () {
        var result = null;
        $.ajax({
            beforeSend: function() {
                alert("Testing");
            },
            url: "FacilitiesAsync",
            success: function(data) {
                result = data;
            },
            complete: function () {
                alert(result);
            }
        });
    });
});
</script>

@using (Html.BeginForm()) {
     <div class="ui-widget">
        <label for="tags">Tags: </label>
        <input id="tags" />
     </div>
}

これは素晴らしい作品です!ただし、コード ビハインドへの呼び出しからデータを取得して、配列 availableTags にデータを入力したいのですが、その方法がわかりません。提案?

4

1 に答える 1

0

実装にはいくつか問題があり、アプローチには 1 つの問題があります。

まず、 にGetFacilitiesBySourceDbAsyncは が含まれていませんawait。この場合、コンパイラは警告を発行し、実際には非同期メソッドではないことを通知します。同期的に実行されます。これは重要な警告です。非同期コードが必要な場合は、完全に非同期にする必要があります。これは、非同期データベース メソッド (ExecuteReaderAsyncなど) を使用することを意味します。

次に、Task.WhenAll呼び出しIndexは無意味です (1 つのタスクしか渡さないため)。また、Indexは同期的ですが非同期メソッドを呼び出しているため、表示されていないコードはおそらく を呼び出しResultていますが、これは ASP.NET では禁止されています。私のブログで説明しているように、コードが実際に非同期になると、これは実際にはデッドロックになります。async

しかし、これらを修正しても、思いどおりにはなりません。このアプローチには問題があり、それはasyncHTTP プロトコルを変更しないことです(これは私のブログへのリンクでもあります)。ASP.NET MVC は非同期メソッドを理解し、asyncアクション メソッドが完了するまで要求を完了しません。AJAX のようなものを使用して、Web ページで目的の処理を実行する必要があります。

于 2013-11-14T10:47:49.600 に答える