다음과 같은 방법으로 백그라운드 작업을 수행합니다.이전 작업이 아직 실행 중인지 확인하고 중지/취소하는 방법은 무엇입니까?
이것은 텍스트 상자 텍스트 변경 이벤트의 연결된 동작입니다.
텍스트가 변경된 후 다시 변경된 경우, 이전 작업이 아직 실행 중인지 두 번째 변경 사항 확인시, 이전 작업이 계속 실행 중인지 확인한 후 중지하고 최신 항목으로 계속 진행하십시오.
public class FindTextChangedBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.TextChanged += OnTextChanged;
}
protected override void OnDetaching()
{
AssociatedObject.TextChanged -= OnTextChanged;
base.OnDetaching();
}
private void OnTextChanged(object sender, TextChangedEventArgs args)
{
var textBox = (sender as TextBox);
if (textBox != null)
{
Task.Factory.StartNew(() =>
{
//Do text search on object properties within a DataGrid
//and populate temporary ObservableCollection with items.
ClassPropTextSearch.init(itemType, columnBoundProperties);
if (itemsSource != null)
{
foreach (object o in itemsSource)
{
if (ClassPropTextSearch.Match(o, searchValue))
{
tempItems.Add(o);
}
}
}
//Copy temporary collection to UI bound ObservableCollection
//on UI thread
Application.Current.Dispatcher.Invoke(new Action(() => MyClass.Instance.SearchMarkers = tempItems));
});
}
}
[편집] 나는 이것을 아직 테스트하지 않았다.
CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
private void OnTextChanged(object sender, TextChangedEventArgs args)
{
var newCts = new CancellationTokenSource();
var oldCts = Interlocked.Exchange(ref this.CancellationTokenSource, newCts);
if (oldCts != null)
{
oldCts.Cancel();
}
var cancellationToken = newCts.Token;
var textBox = (sender as TextBox);
if (textBox != null)
{
ObservableCollection<Object> tempItems = new ObservableCollection<Object>();
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var search = Task.Factory.StartNew(() =>
{
ClassPropTextSearch.init(itemType, columnBoundProperties);
if (itemsSource != null)
{
foreach (object o in itemsSource)
{
cancellationToken.ThrowIfCancellationRequested();
if (ClassPropTextSearch.Match(o, searchValue))
{
tempItems.Add(o);
}
}
}
}, cancellationToken);
//Still to be considered.
//If it gets to here and it is still updating the UI then
//what to do, upon SearchMarkers being set below do I cancel
//or wait until it is done and continue to update again???
var displaySearchResults = search.ContinueWith(resultTask =>
MyClass.Instance.SearchMarkers = tempItems,
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion,
ui);
}
}
당신이 작업에 CancellationTokenSource에서 취소 토큰을 전달하고 변수를 증가시켜 텍스트를 변경 횟수의 수를 유지하는 경우
확실히 4.5까지 타겟팅. 당신이 제안한 것을 그냥 실행하십시오. – Hank
그럴 경우 위의 코드를 상당히 개선 할 수 있습니다. Simpler/bettet 예외 처리, 조절 (비동기 임에도 불구하고 현재 구현에서 UI가 상당히 느려지는 것을 느낄 수 있습니다.) 등이 있습니다. 나는 자유 분이 생겼을 때 몇 가지 추가적인 명제로 나의 대답을 편집 할 것이다. –
감사합니다! 또한 위의 예제에 추가되어 현재 작업의 내용을 보여줍니다. – Hank