nats
3월 15, 2024, 6:25오전
1
Infos에는 구간 데이터, ID가 포함
intervalDatas에는 구간별 데이터, ID, 데이터 갯수가 표함
30초 단위의 0, 1, 2, 3 ID구간이 반복되어
60초 단위에 4(0, 1 두번 사이클 포함), 5(2, 3 두번 사이클 포함)되어
각각 주기마다에 실행되는 코드
[Infos 데이터]
[원하는 결과 데이터]
void OnIntervalData()
{
uint checkTime = (uint)DateTime.Now.TimeOfDay.TotalSeconds;
while(intervalThread != null)
{
DataInfo[] dataInfos = MainDataContext.DataInfoCollection.ToArray();
try
{
if (dataInfo.IntervalData > 0)
{
IInfo[] Infos = dataInfo.LocationInfoCollection.ToArray();
// PeriodIndex(초 단위 데이터)가 몇인지 몇개가 될지는 모름.
var groupedInfos = Infos.GroupBy(x => x.PeriodIndex);
// PeriodIndex로 구분되어진 group만큼 ListData를 복제함.
// 현재 ListData는 다른 Thread에서 1초마다 Merge되고있음.
foreach (var group in groupedInfos)
{
// 원본 ListData를 Distinct 작업을 수행
ListData.Distinct();
// ListData를 복제하여 새로운 리스트에 저장 (현재 애매한 부분...)
// group에 속한 데이터를 처리를 어떻게 해야할지...
List<IntervalData> intervalDatas = group.Select(x => x.GetStandardDeviation(ListDataCopy)).ToList();
// intervalDatas를 이용하여 나머지 작업 수행
foreach (IntervalData i in intervalDatas)
{
// 작업 수행 코드
if ((checkTime % i.PeriodIndex) == 0)
{
#region 데이터처리
#endregion
}
}
// List Clear 시기는?
}
}
}
catch (Exception ex) { }
#region TimeCheck
checkTime++;
double wait = (double)checkTime - DateTime.Now.TimeOfDay.TotalSeconds;
if (wait > 0) Thread.Sleep((int)(wait * 1000.0));
checkTime %= 86400;
#endregion
}
}
1개의 좋아요
질문에 나타난 식별자와 코드의 식별자가 거의 일치하지 않아 질문 자체를 이해하기 어렵군요.
꼭 필요한 정보는 소스 코드의 주석이 아니라, 질문의 문장 속에 넣어 보세요.
자신의 코드가 동작하지 않는다면, 차라리 적지 않는 게 좋습니다.
사용 중인 프레임워크, 닷넷 버전, 현재 상황, 필요한 결과로 요약해보세요.
2개의 좋아요
BOBx5
3월 15, 2024, 9:40오전
3
보기 어려워 수정해서 달아놓습니다…
void OnIntervalData()
{
uint checkTime = (uint)DateTime.Now.TimeOfDay.TotalSeconds;
while (intervalThread != null)
{
DataInfo[] dataInfos = MainDataContext.DataInfoCollection.ToArray();
try
{
if (dataInfo.IntervalData > 0)
{
IInfo[] Infos = dataInfo.LocationInfoCollection.ToArray();
// PeriodIndex(초 단위 데이터)가 몇인지 몇개가 될지는 모름.
var groupedInfos = Infos.GroupBy(x => x.PeriodIndex);
// PeriodIndex로 구분되어진 group만큼 ListData를 복제함.
// 현재 ListData는 다른 Thread에서 1초마다 Merge되고있음.
foreach (var group in groupedInfos)
{
// 원본 ListData를 Distinct 작업을 수행
ListData.Distinct();
// ListData를 복제하여 새로운 리스트에 저장 (현재 애매한 부분...)
// group에 속한 데이터를 처리를 어떻게 해야할지...
List<IntervalData> intervalDatas = group.Select(x => x.GetStandardDeviation(ListDataCopy)).ToList();
// intervalDatas를 이용하여 나머지 작업 수행
foreach (IntervalData i in intervalDatas)
{
// 작업 수행 코드
if ((checkTime % i.PeriodIndex) == 0)
{
#region 데이터처리
#endregion
}
}
// List Clear 시기는?
}
}
}
catch (Exception ex) { }
#region TimeCheck
checkTime++;
double wait = (double)checkTime - DateTime.Now.TimeOfDay.TotalSeconds;
if (wait > 0) Thread.Sleep((int)(wait * 1000.0));
checkTime %= 86400;
#endregion
}
}
3개의 좋아요
여기 계시는 분들이 친절하셔서 질문만 잘 올려주시면 답변 받으실 수 있으니 살펴보시고 보완해주세요^^
1개의 좋아요
원하시는 결과가 맞을 지 모르겠지만,
일정 주기 마다 이벤트를 발행하는 객체를 아래와 같이 정의할 수 있습니다.
public sealed class Ticker : IDisposable
{
public Ticker(int intervalInSeconds) => _interval = intervalInSeconds;
private CancellationTokenSource _cts = new();
// bool : is the total tick count even?
public event EventHandler<bool> Ticked = (s, e) => { };
public bool IsPausing => _skips;
private bool _skips;
private bool _isBeating;
private readonly int _interval;
public void StartPause()
{
if(_isBeating is false) { Init(); _isBeating = true; return; }
_skips = !_skips;
}
private async void Init()
{
if(_isBeating) return;
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(_interval));
bool isEven = false;
while (await timer.WaitForNextTickAsync(_cts.Token))
{
if(_skips) continue;
if(_cts.IsCancellationRequested) break;
Ticked.Invoke(null, isEven = !isEven);
}
}
public void Dispose() => _cts.Cancel();
}
이 객체는 Ticked 이벤트를 발행할 때, 홀수 번 째 이벤트인지 짝수번째 이벤트인지를 알려 줍니다.
사용
internal class Program
{
private static IEnumerable<int> Infos { get
{
int infoId = 0;
while(true) yield return infoId++;
}}
// 바인딩 소스
private static readonly List<string> s_Results = [];
private static void UpdateBindingSource(int count)
{
foreach (var id in Infos)
{
if(count-- <= 0 ) break;
s_Results.Add($"id: {id}");
}
}
private static void TickedHandler(object? s, bool isEven) =>
UpdateBindingSource( isEven ? 6 : 4);
private static void Render()
{
if(s_Results.Count != 0) {
System.Console.WriteLine(string.Join(" | ", s_Results));
s_Results.Clear();
}
}
static void Main(string[] args)
{
using var ticker = new Ticker(1);
ticker.Ticked += TickedHandler;
System.Console.WriteLine("Press s to toggle rendering or x to terminate");
while(true)
{
Render();
if (Console.KeyAvailable){
var cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.S) ticker.StartPause();
else if(cki.Key == ConsoleKey.X) break;
}
}
}
}
UI 프레임워크를 사용 중일 것 같아 콘솔앱에 무한 루프를 넣었습니다.
결과
Press s to toggle rendering or x to terminate
(s 누름)
id: 0 | id: 1 | id: 2 | id: 3
id: 0 | id: 1 | id: 2 | id: 3 | id: 4 | id: 5
id: 0 | id: 1 | id: 2 | id: 3
id: 0 | id: 1 | id: 2 | id: 3 | id: 4 | id: 5
…
(s 누름) => 멈춤.
(s 누름) => 다시 시작.
(x 누름) => 종료.
1개의 좋아요