У меня есть обработчик асинхронных событий, который запускается в моем поле ввода всякий раз, когда изменяется текст.Это приложение Xamarin.Forms, и я использую обработчик событий TextChanged
для того, чтобы имитировать функциональность «сверхпечатного типа» в моей записи, например, для написания текста при вставке ключа в активный.Однако иногда это приводит к блокировке приложения после вызова await Task.Yield ().Этот вызов необходим для получения правильного поведения, в противном случае каретка не переходит в правильную позицию после выполнения вызова.Я не могу понять, почему код передает и как решить эту проблему, поэтому любая помощь / совет будут оценены.Я предполагаю, что проблема связана с моим недостаточным знанием асинхронного программирования.
private static async void OnOvertypeTextChanged(object sender, TextChangedEventArgs e)
{
var guid = Guid.NewGuid();
Debug.WriteLine($"{DateTime.Now.ToString()}: START {guid.ToString()}");
var entry = sender as CustomEntry;
if (entry.IsOvertypeRunning)
{
return;
}
else
{
entry.IsOvertypeRunning = true;
}
try
{
entry.TextChanged -= OnOvertypeTextChanged;
//Update value as in overtype mode
var oldVal = e.OldTextValue;
var newVal = e.NewTextValue;
int? carret = null;
//If new string is longer, we should go into overtype mode, otherwise ignore it
if (newVal?.Length > oldVal?.Length)
{
var i = entry.CursorPosition;
var overtyped = oldVal.Substring(0, i) + newVal[i] + ((oldVal.Length > (i + 1)) ? oldVal.Substring(i + 1) : "");
entry.Text = overtyped;
carret = i + 1;
//Check if new overtyped value is longer than max allowed size
if (entry.OvertypeLength != -1 && entry.Text.Length > entry.OvertypeLength)
{
var cut = entry.Text.Substring(0, entry.OvertypeLength);
//If new text would be longer, then cut it
entry.Text = cut;
if (carret >= cut.Length)
{
carret = cut.Length;
}
}
}
//For some reason, this is needed...
if (carret != null)
{
Debug.WriteLine($"{DateTime.Now.ToString()}: WAITING {guid.ToString()}");
await Task.Yield();
Debug.WriteLine($"{DateTime.Now.ToString()}: DONE_WAITING {guid.ToString()}");
Debug.WriteLine($"{DateTime.Now.ToString()}: SETTING_CURSOR {guid.ToString()} @ {carret.Value.ToString()}");
entry.CursorPosition = carret.Value;
Debug.WriteLine($"{DateTime.Now.ToString()}: CURSOR_SET {guid.ToString()}");
}
Debug.WriteLine($"{DateTime.Now.ToString()}: DONE {guid.ToString()}");
}
catch (Exception ex)
{
Debug.WriteLine($"{DateTime.Now.ToString()}: ERROR {guid.ToString()}", ex);
}
finally
{
entry.IsOvertypeRunning = false;
entry.TextChanged += OnOvertypeTextChanged;
Debug.WriteLine($"{DateTime.Now.ToString()}: END {guid.ToString()}");
}
}
Так что произойдет, что все будет работать нормально, сразу после нескольких успешных событий фокусировки / расфокусировки в Entry,он будет зависать.
Таким образом, при регистрации будет что-то вроде:
[0:] 18. 12. 2018 17:57:26: START bba4b754-8f22-4a14-ae28-8536d3a1e3d1
[0:] 18. 12. 2018 17:57:26: WAITING bba4b754-8f22-4a14-ae28-8536d3a1e3d1
[0:] 18. 12. 2018 17:57:26: DONE_WAITING bba4b754-8f22-4a14-ae28-8536d3a1e3d1
[0:] 18. 12. 2018 17:57:26: SETTING_CURSOR bba4b754-8f22-4a14-ae28-8536d3a1e3d1 @ 14
[0:] 18. 12. 2018 17:57:26: CURSOR_SET bba4b754-8f22-4a14-ae28-8536d3a1e3d1
[0:] 18. 12. 2018 17:57:26: DONE bba4b754-8f22-4a14-ae28-8536d3a1e3d1
[0:] 18. 12. 2018 17:57:26: END bba4b754-8f22-4a14-ae28-8536d3a1e3d1
[0:] 18. 12. 2018 17:57:26: START 71bf9809-6217-4d73-94df-817042a251b9
[0:] 18. 12. 2018 17:57:26: WAITING 71bf9809-6217-4d73-94df-817042a251b9
[0:] 18. 12. 2018 17:57:26: DONE_WAITING 71bf9809-6217-4d73-94df-817042a251b9
[0:] 18. 12. 2018 17:57:26: SETTING_CURSOR 71bf9809-6217-4d73-94df-817042a251b9 @ 14
[0:] 18. 12. 2018 17:57:26: CURSOR_SET 71bf9809-6217-4d73-94df-817042a251b9
[0:] 18. 12. 2018 17:57:26: DONE 71bf9809-6217-4d73-94df-817042a251b9
[0:] 18. 12. 2018 17:57:26: END 71bf9809-6217-4d73-94df-817042a251b9
[0:] 18. 12. 2018 17:57:31: START f9fca969-e141-4a07-968d-e32616323995
[0:] 18. 12. 2018 17:57:31: WAITING f9fca969-e141-4a07-968d-e32616323995
И после этого приложение перестает отвечать на запросы и отображает сообщение «Приложение X не отвечает ...»
При вызове сервисов HttpClient со мной происходили такие же асинхронные "тупики", как описано в CLICK
Я предполагаю, что проблемы могут быть похожими?