내 시나리오는 다음과 같습니다. 사용자가지도상의 점 집합에 대한 개방 기간을 시작하는 WPF 버튼을 클릭합니다. 사용자가 "수집 완료"버튼을 클릭하면 CollectPoints()
작업을 완료하고 싶습니다. 여기 CancellationToken을 사용하여 중첩 된 작업을 중단하십시오.
private CancellationTokenSource _cancellationToken;
public virtual async void RecordSegment(IRoadSegment segment)
{
_cancellationToken = new CancellationTokenSource();
var token = _cancellationToken.Token;
// await user clicking points on map
await CollectPoints(token);
// update the current segment with the collected shape.
CurrentSegment.Shape = CurrentGeometry as Polyline;
}
// collect an arbitrary number of points and build a polyline.
private async Task CollectPoints(CancellationToken token)
{
var points = new List<MapPoint>();
while (!token.IsCancellationRequested)
{
// wait for a new point.
var point = await CollectPoint();
points.Add(point);
// add point to current polyline
var polylineBuilder = new PolylineBuilder(points, SpatialReferences.Wgs84);
CurrentGeometry = polylineBuilder.ToGeometry();
// draw points
MapService.DrawPoints(CurrentGeometry);
}
}
// collect a point from map click.
protected override Task<MapPoint> CollectPoint()
{
var tcs = new TaskCompletionSource<MapPoint>();
EventHandler<IMapClickedEventArgs> handler = null;
handler = (s, e) =>
{
var mapPoint = e.Geometry as MapPoint;
if (mapPoint != null)
{
tcs.SetResult(new MapPoint(mapPoint.X, mapPoint.Y, SpatialReferences.Wgs84));
}
MapService.OnMapClicked -= handler;
};
MapService.OnMapClicked += handler;
return tcs.Task;
}
public void StopSegment(){
// interrupt the CollectPoints task.
_cancellationToken.Cancel();
}
내보기 모델의 관련 부분은 다음과 같습니다 :
가 여기 내 SegmentRecorder
클래스의 조각입니다
public SegmentRecorder SegmentRecorder { get; }
public RelayCommand StopSegment { get; }
public ViewModel(){
StopSegment = new RelayCommand(ExecuteStopSegment);
SegmentRecorder = new SegmentRecorder();
}
// execute on cancel button click.
public void ExecuteStopSegment(){
SegmentRecorder.StopSegment();
}
내가 선
while (!token.IsCancellationRequested)
에 중단 점을 넣어
및 취소 버튼을 클릭 , 나는 결코 그 점에 도착하지 않는다.
취소 토큰을 올바르게 사용하고 있습니까? 그것은 while
조건 !token.IsCancellationRequested
당신이 CancellationTokenSource
의 Cancel()
방법을 호출 한 후 처음으로 안타 때마다
측면 참고 : 이벤트 핸들러가 아닌 방법에 대한'비동기 void'을 사용할 수 없습니다. – dymanoid
당신은'CollectPoint' 내부에서 취소를 처리 할 필요가있을 것입니다, 그것은 아마도 그것이 지금 기다리고있는 곳일 것입니다. – JSteward
사용자가 포인트 수집을 중지하면 CollectPoint 태스크가 완료 될 때까지 적어도 하나 이상의 포인트를 수집해야합니다.이 태스크는 'while'실행을 일시 중지합니다. 'CollectPoint' 외부의'tcs '를 잡고 완료하거나 취소 할 때 취소하면 예상대로 완료됩니다. – JSteward