0

サーバー上で動作する Web API アプリケーションを作成しました。クライアント側には、テスト用に Android アプリケーションがあります。とてもシンプルです。ユーザーはユーザー名とパスワードを入力し、さらに 2 つの文字列 DeviceId と DeviceName を送信します。ユーザーは既に定義されているサービスによって検証され、すべてがうまくいけば、次の 3 つのことが起こります。

  1. ユーザーが作成され、データベースに保存されます。
  2. ユーザーに情報メールが送信されます。
  3. アクセストークンがクライアントに返されます。

しかし、コードにいくつかの変更を加えた後、サーバーからの応答に時間がかかりすぎ、モバイル ユーザーのタイムアウトが頻繁に発生します。

コードの特定の部分を追加した後、タイムアウトが発生し始めたことに気付きました。

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
string deviceId = rgx.Replace(model.DeviceId, "");

この部分は、DeviceID 文字列から英数字以外のすべての文字を削除するために使用されます。ユーザーがこの変数にスラッシュまたはバックスラッシュを持っている場合、このコードを追加する前に JSON 関連のエラーが発生するため、これは重要です。

だから私の質問は: Regex クラスとそのメソッドがサーバー上で混乱を引き起こし、サーバーからの応答に時間がかかりすぎる可能性はありますか?

それが助けになる場合、これは問題のある呼び出しのコードです:

[Route("registration/request")]
public async Task<HttpResponseMessage> RegistrationRequest(Registration model)
{
    try
    {
        MatrixLogManager.Info("Starting token creating.");

        var request = HttpContext.Current.Request;
        var tokenServiceUrl = request.Url.GetLeftPart(UriPartial.Authority) + request.ApplicationPath + "/Token";

        MatrixLogManager.Info("Checking if model is valid.");
        if (!ModelState.IsValid)
        {
            return Request.CreateResponse(BadRequest(ModelState));
        }
        using (MatrixServiceLayerLogin login = new MatrixServiceLayerLogin())
        {
            if (login.LoginUser(model.UserName, model.Password, true, true))
            {
                var personId = login.GetPersonId();

                MatrixLogManager.Debug("User " + model.UserName + " successfully logged in on MatrixSTS.");
                try
                {
                    using (var authRepo = new AuthRepository())
                    {
                        MatrixLogManager.Info("Changing deviceID format.");
                        Regex rgx = new Regex("[^a-zA-Z0-9 -]");
                        model.DeviceId = rgx.Replace(model.DeviceId, "");
                        MatrixLogManager.Debug(model.DeviceId);
                        MatrixLogManager.Debug("Saving user: " + model.DeviceId);
                        ApplicationUser appUser = new UserFactory().CreateApplicationUser(model, personId);

                        IdentityResult result = await authRepo.RegisterUser(appUser);
                        EMailService.SendEmail(appUser);
                        IHttpActionResult errorResult = GetErrorResult(result);

                        MatrixLogManager.Debug("Saved user: " + model.DeviceId);
                        if (errorResult != null)
                        {
                            return Request.CreateResponse(errorResult);
                        }

                        using (var client = new HttpClient())
                        {
                            var requestParams = new List<KeyValuePair<string, string>>
                                        {
                                            new KeyValuePair<string, string>("grant_type", "password"),
                                            new KeyValuePair<string, string>("username", appUser.UserName),
                                            new KeyValuePair<string, string>("password", "0000")
                                        };

                            var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
                            var tokenServiceResponse = await client.PostAsync(tokenServiceUrl, requestParamsFormUrlEncoded);
                            var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
                            var responseCode = tokenServiceResponse.StatusCode;
                            var responseMsg = new HttpResponseMessage(responseCode)
                            {
                                Content = new StringContent(responseString, Encoding.UTF8, "application/json")
                            };

                            responseMsg.Headers.Add("PSK", appUser.PSK);
                            return responseMsg;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MatrixLogManager.Error("Error: ", ex);
                    throw ex;
                }
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid username or password.");
            }
        }
    }
    catch (Exception ex)
    {
        MatrixLogManager.Error(string.Format("Error while trying registring user: Exception = {0} InnerException {1}", ex.Message, ex.InnerException.Message));
        throw;
    }
}

PS もう一つ。このコードを自分のマシンでテストすると、ローカルでの応答時間はそれほど長くなく、すべてうまくいきます。問題は、このコードがサーバーに公開されたときにのみ発生し、時々発生します。

4

1 に答える 1

0

ここには 2 つの問題があります。

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
model.DeviceId = rgx.Replace(model.DeviceId, "");

まず、正規表現コンストラクターを使用することで、適用するたびにシステムに新しい Regex オブジェクトを作成させます。代わりに静的メソッドのいずれかを使用すると、システムは Regex オブジェクトを初めて使用するときに自動的にキャッシュします。または、事前に正規表現を作成して静的変数に格納することもできます。

第二に、不要な文字を一度に 1 つずつ置換しているため、非常に非効率的です。+一度に望ましくない文字のシーケンス全体に一致するように、正規表現の末尾にa を追加します。

model.DeviceId = Regex.Replace(model.DeviceId, "[^a-zA-Z0-9 -]+", "");
于 2015-04-23T12:10:59.357 に答える