-2

일시적으로 변경할 수있는 C# Windows 서비스의 플래그 값이 있지만 일정 기간 후에 자동으로 일부 기본값으로 되돌아갑니다. 클래스의 골자는이 모든 잘 좋은이Task.Delay()를 사용하여 값을 다시 설정하는 클래스 만들기

public class Revertable<T> 
{ 
    public readonly T DefaultValue; 
    public T Value { get; protected set; } 

    public async Task SetValue(T newValue, TimeSpan resetDelay) 
    { 
     Value = newValue; 
     await Task.Delay(resetDelay); 
     Value = DefaultValue; 
    } 

    public void ResetValue() 
    { 
     Value = DefaultValue; 
    } 
} 

처럼 보일하지만, 누군가가 다시 SetValue를 호출하는 경우, 지금은 아마도 eachothers의 발가락에 단계 수있는 계획이 개 인터럽트를해야합니다. 한 가지 생각은 인 경우 SetValue을 호출하려는 모든 요청을 거부하는 것입니다. 너무 어설픈 느낌이지만, 일종의 작품. 그러나 어떤면에서 누군가가 언제든지 값을 설정 해제 할 수있는 능력이 필요합니다.

나는 CancellationTokenSource/CancellationToken 구조를 조사 해왔다. 그러나 실제로이 모든 것을 설정하는 방법은 어리둥절 해. 그것은 내가 CancellationTokenSource 회원 (내 ResetValue() 또는 다른 사람들이 사용할 수있는)에 추가해야하고, Task.Delay() 호출에 제공해야합니다. 누군가 ResetValue()으로 전화하면 토큰 소스가 취소를 시작하고 계속 진행합니다. async 프로그램에

... 
private CancellationTokenSource TokenSource; 
public async Task SetValue(T newValue, TimeSpan resetDelay) 
{ 
    if (!Value.Equals(DefaultValue)) 
     return; 

    Value = newValue; 
    using (CancellationTokenSource src = new CancellationTokenSource()) 
    { 
     TokenSource = src; 
     await Task.Delay(resetDelay, src.Token); 
    } 
    Value = DefaultValue; 
} 

public void ResetValue() 
{ 
    if (TokenSource != null && TokenSource.Token.CanBeCanceled) 
    { 
     TokenSource.Cancel(); 
     TokenSource.Dispose(); 
    } 
    Value = DefaultValue; 
} 

내가 다소 새로운 해요, 난 완전히 비교적 정직해야 것 같아 뭔가를하고 서투른 솜씨 싶지 않은 : 그래서 수정, 클래스의 내장은 다음과 같을 것 (또는 처분되지 않은 토큰 소스를 주위에 떠 다니십시오). 이 문제를 해결할 수있는 유효한 방법 인 것 같습니까? 아니면 누군가가 더 좋은 방법을 제안 할 수 있습니까?

+0

작동합니까? 시도한 해결책으로 어떤 문제가 있는지 알려줍니다. – Servy

+1

비동기/대기를 사용하지 않고'MemoryCache'를 사용하고 딜레이 후에 만료되는 롤링 윈도우를 가지므로 모든 캐시 미스가 기본값을 반환합니다. –

+0

@Servy 그것은 그렇다. (영구히 처형 된 상태이기 때문에 나는'using' 문을 제거해야만했다.) 나는 이것이 좋은 접근 방법이거나'비동기'프로그래밍의 사용, 또는 내가 고려하지 않은 잡기가 있다면 더 걱정된다. 나는 지금 며칠 동안이 일을 끝내 버렸다. – Xedni

답변

2

스레드 또는 작업이 전혀 필요하지 않습니다. 타임 스탬프를 사용하고 (자동이 아닌) 속성으로 필드를 보호하십시오.

public class Revertable<T> 
{ 
    public readonly T DefaultValue; 
    public readonly TimeSpan ResetDelay; 

    private T _currentValue; 
    private DateTimeOffset _resetTime; 

    public Revertable(T defaultValue, TimeSpan resetDelay) 
    { 
     this.DefaultValue = defaultValue; 
     this.ResetDelay = resetDelay; 
     _currentValue = defaultValue; 
     _resetTime = DateTimeOffset.MinValue; 
    } 

    public T Value 
    { 
     get 
     { 
      return (System.DateTimeOffset.Now > _resetTime) 
       ? DefaultValue 
       : _currentValue; 
     } 
     set 
     { 
      _currentValue = value; 
      _resetTime = System.DateTimeOffset.Now.Add(this.ResetDelay); 
     } 
    } 
} 

public static void Main() 
{ 
    var r = new Revertable<string>("Default value", new TimeSpan(0,0,1)); 
    Console.WriteLine("Value is now {0}", r.Value); 
    r.Value = "Changed"; 
    for (int i = 0; i<30; i++) 
    { 
     System.Threading.Thread.Sleep(100); 
     Console.WriteLine("Value is now {0}", r.Value); 
    } 
} 

출력 : DotNetFiddle 볼 수

Value is now Default value 
Value is now Changed 
Value is now Changed 
Value is now Changed 
Value is now Changed 
Value is now Changed 
Value is now Changed 
Value is now Changed 
Value is now Changed 
Value is now Changed 
Value is now Default value 
Value is now Default value 
Value is now Default value 
Value is now Default value 
Value is now Default value 

전체 코드입니다.

+2

System.DateTime.UtcNow는 System.DateTimeOffset.Now보다 약간 가벼우 며 동일한 계산을 수행하는 데 사용할 수 있습니다. –

+2

나는 가정한다. 저는 dev 팀이 말한 것처럼 좋은 습관을 형성하려고합니다. (https://blogs.msdn.microsoft.com/bclteam/2007/06/14/datetimeoffset-a-new-datetime-structure-in -net-3-5-justin-van-patten /) "DateTimeOffset은 가장 일반적인 날짜 시간 시나리오에 사용할 새로운 기본 형식입니다." 성능이 정말로 걱정된다면 [Environment.TickCount] (https://msdn.microsoft.com/en-us/library/system.environment.tickcount (v = vs.110) .aspx)를 대신 사용하십시오. –

+0

흥미로운 접근 방식; 감사! – Xedni