1) Это хороший подход?
В этом подходе нет ничего плохого.
2) Можем ли мы улучшить его с точки зрения производительности?
Не должно быть никаких проблем с производительностью при использовании метода расширения, но вы можете измерить до 100% определенный.Вы создаете ситуацию упаковки и распаковки с использованием кастинга от object
до button
.Не могли бы вы просто использовать Button
.Используйте ViewElement
, если вы хотите поддерживать несколько типов элементов.Кроме того, существуют штрафы за использование async await
, но они минимальны и необходимы, чтобы не блокировать пользовательский интерфейс.Вы можете повысить производительность, устранив необходимость повторного создания контекста, добавив .ConfigureAwait(false)
к своим задачам, но в вашем случае вам нужен контекст, чтобы снова включить кнопку.Использование dynamic
кажется ненужным и имеет некоторые накладные расходы.
3) Правильно ли я использую Async?
Вам не нужно await
aTask
, если метод просто возвращает Task
.Вы можете await
это из вызывающего метода.Это уменьшит нагрузку на компилятор и может повысить производительность.Я не проверял это раньше, хотя.
Добавочный номер
public static async Task<ResultViewModel<T>> ExecuteAsyncOperation<T>(this Task<HttpResponseMessage> operation, Button button)
{
ResultViewModel<T> resultModel = new ResultViewModel<T>();
try
{
if (button != null)
button.IsEnabled = false;
HttpResponseMessage RawResult = await operation;
string Response = await RawResult.Content.ReadAsStringAsync();
resultModel.Status = RawResult.StatusCode;
if (RawResult.IsSuccessStatusCode)
{
var responseObj = JsonConvert.DeserializeObject<T>(Response);
resultModel.Result = responseObj;
}
else
{
//create an error model instead of using dynamic I am guessing modelstate here
List<ModelState> responseObj = JsonConvert.DeserializeObject<List<ModelState>>(Response);
resultModel.Errors = new List<string>();
foreach (ModelState modelState in responseObj)
{
foreach (var error in modelState.Errors)
{
resultModel.Errors.Add(error.ToString());
}
}
}
}
catch (Exception ex)
{
resultModel.Status = HttpStatusCode.InternalServerError;
resultModel.Errors = new List<string>() { "Some error occurred. Please try again." };
}
finally
{
if (button != null)
button.IsEnabled = true;
}
return resultModel;
}
Вызов
var button = sender as Button;
if (button != null)
{
ResultViewModel<TokenModel> response = await new Service(Settings.BaseUrl).Login(loginModel).ExecuteAsyncOperation<TokenModel>(sender);
}
Запрос
public Task<HttpResponseMessage> Login(LoginViewModel loginModel)
{
var dataList = new List<KeyValuePair<string, string>>();
dataList.Add(new KeyValuePair<string, string>("grant_type", "password"));
dataList.Add(new KeyValuePair<string, string>("username", loginModel.Email));
dataList.Add(new KeyValuePair<string, string>("password", loginModel.Password));
var request = new HttpRequestMessage()
{
RequestUri = new Uri(this.BaseUrl + "token"),
Method = HttpMethod.Post,
Content = new FormUrlEncodedContent(dataList)
};
return Client.SendAsync(request);
}