Я столкнулся с проблемами с этим. Я попробовал каждый из ответов здесь, и, поскольку я нахожусь в универсальном приложении Xamarin, мне, кажется, не хватает определенных вещей, которые требуются в каждом из этих ответов, и я не хотел добавлять больше пакетов или библиотек. Мое решение работает именно так, как я ожидаю, и я не столкнулся с какими-либо проблемами с ним. Надеюсь, это кому-нибудь поможет.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace OrderScanner.Models
{
class Debouncer
{
private List<CancellationTokenSource> StepperCancelTokens = new List<CancellationTokenSource>();
private int MillisecondsToWait;
private readonly object _lockThis = new object(); // Use a locking object to prevent the debouncer to trigger again while the func is still running
public Debouncer(int millisecondsToWait = 300)
{
this.MillisecondsToWait = millisecondsToWait;
}
public void Debouce(Action func)
{
CancelAllStepperTokens(); // Cancel all api requests;
var newTokenSrc = new CancellationTokenSource();
lock (_lockThis)
{
StepperCancelTokens.Add(newTokenSrc);
}
Task.Delay(MillisecondsToWait, newTokenSrc.Token).ContinueWith(task => // Create new request
{
if (!newTokenSrc.IsCancellationRequested) // if it hasn't been cancelled
{
CancelAllStepperTokens(); // Cancel any that remain (there shouldn't be any)
StepperCancelTokens = new List<CancellationTokenSource>(); // set to new list
lock (_lockThis)
{
func(); // run
}
}
});
}
private void CancelAllStepperTokens()
{
foreach (var token in StepperCancelTokens)
{
if (!token.IsCancellationRequested)
{
token.Cancel();
}
}
}
}
}
Это называется так ...
private Debouncer StepperDeboucer = new Debouncer(1000); // one second
StepperDeboucer.Debouce(() => { WhateverMethod(args) });
Я бы не рекомендовал это ни для чего, когда машина могла бы отправлять сотни запросов в секунду, но для пользовательского ввода она работает превосходно. Я использую его на степпере в приложении для Android / IOS, которое вызывает API на шаге.
Вы хотите прочитать (запросить) данные в определенном порядке, или вы действительно хотите изменить порядок данных в xml? Чтобы читать в определенном порядке, просто используйте метод LINQ OrderBy
:
var qry = from book in el.Elements("book")
orderby (int)book.Element("year")
select new
{
Year = (int)book.Element("year"),
Title = (string)book.Element("title"),
Author = (string)book.Element("author")
};
(отредактировано) Изменить xml сложнее ... может быть, что-то вроде:
var qry = (from book in el.Elements("book")
orderby (int)book.Element("year")
select book).ToArray();
foreach (var book in qry) book.Remove();
foreach (var book in qry) el.Add(book);
Это выполнимо, но немного странно:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
string xml =
@"<books>
<book>
<author>sadfasdf</author>
<title>asdfasdf</title>
<year>1999</year>
</book>
<book>
<author>asdfasdf</author>
<title>asdfasdf</title>
<year>1888</year>
</book>
<book>
<author>asdfsdf</author>
<title>asdfasdf</title>
<year>1777</year>
</book>
</books>";
XElement root = XElement.Parse(xml);
List<XElement> ordered = root.Elements("book")
.OrderBy(element => (int)element.Element("year"))
.ToList();
root.ReplaceAll(ordered);
Console.WriteLine(root);
}
}
Обратите внимание, что если у вас есть другой контент в корневом узле, вы должны вызвать Remove
для каждого XElement
] перед их добавлением вместо простого вызова RemoveAll
.