현재 데이터베이스에서 "프로세스 대기 중"이라고 판단한 각 요청에 대해 Task를 생성하는 서비스를 작성 중입니다.Task.WhenAny 사전 사용
프로세스가 길어질 수 있으며 토큰을 사용하여 작업을 취소하려는 경우 프로세스가 취소되어야하는 경우 루프가 반복 될 때마다 서비스를 확인해야합니다. 그래서 작업에 연결된 요청의 ID를 저장해야합니다. 나는 다음과 같은 사전 내 정적 클래스를하는 것에 대한 생각
: 그것은 존재하는 더 나은 솔루션입니다하지만 여전히 작동 하나 내가 생각하면 나도 몰라
public static Dictionary<Int32, Task<Int32>> _tasks = new Dictionary<int, Task<int>>();
.
이제 Task.WhenAny (..) 중 하나가 끝날 때 알기를 원합니다. 문제는 Task.WhenAny (..)가 배열을 허용하지만 Dictionary는 허용하지 않는다는 것입니다. 사전을 WhenAny에 전달하는 것에 대해서는 아무 것도 보지 못했고 전체 워크 플로우에 대한 작업을 시작하기 전에 워크 플로우의 각 키포인트에 대한 솔루션을 원했습니다. 나는 사전 값의 목록을 얻을 수 있었지만 아마 id 링크를 잃어 버렸을 것이다. 그래서 나는 정말로 무엇을해야할지 모른다.
해결책이 있습니까? 나는 내 자신의 "WhenAny"를 재창조하고 싶지 않고 가능한지 모르지만 모든 행의 상태를 파싱 할 수 있다고 가정합니다. 그러나 그것이 유일한 선택이라면, 그렇게 할 것입니다.
나는이 방법으로 요청의 ID를 저장하는 것이 좋은 방법이 아니라는 사실에 대해서도 열려 있으며이 경우에는 다른 제안을 할 수있다.
편집 : CODE 주문에 따라 제품에 내가 일하게 될 것 같다이 코드를 사용하여 종료 답변. 이제는 파일 작성이 아니라보다 복잡한 작업으로 테스트 해 보겠습니다! :)
public static class Worker
{
public static List<Task<Int32>> m_tasks = new List<Task<Int32>>();
public static Dictionary<Int32, CancellationTokenSource> m_cancellationTokenSources = new Dictionary<int, CancellationTokenSource>();
public static Int32 _testId = 1;
public static void run()
{
//Clean
Cleaner.CleanUploads();
Cleaner.CleanDownloads();
#region thread watching
if (m_tasks.Count > 0)
{
#region thread must be cancel
//Cancel thread
List<Task<Int32>> _removeTemp = new List<Task<Int32>>();
foreach (Task<Int32> _task in m_tasks)
{
if (DbWorker.mustBeCancel((Int32)_task.AsyncState))
{
m_cancellationTokenSources[(Int32)_task.AsyncState].Cancel();
//Cancellation actions
//task must be remove
_removeTemp.Add(_task);
}
}
foreach(Task<Int32> _taskToRemove in _removeTemp)
{
m_tasks.Remove(_taskToRemove);
}
#endregion
#region Conversion lookup
// Get conversion if any
// Create task
CancellationTokenSource _srcCancel = new CancellationTokenSource();
m_cancellationTokenSources.Add(_testId, _srcCancel);
m_tasks.Add(Task.Factory.StartNew(_testId => testRunner<Int32>((Int32)_testId), _testId, _srcCancel.Token));
_testId++;
// Attach task
#endregion
}
#endregion
else
{
CancellationTokenSource _srcCancel = new CancellationTokenSource();
m_cancellationTokenSources.Add(_testId, _srcCancel);
m_tasks.Add(Task.Factory.StartNew(_testId => testRunner<Int32>((Int32)_testId), _testId, _srcCancel.Token));
_testId++;
}
}
internal static void WaitAll()
{
Task.WaitAll(m_tasks.ToArray());
}
public static Int32 testRunner<T>(T _id)
{
for (Int32 i = 0; i <= 1000000; i++)
{
File.AppendAllText(@"C:\TestTemp\" + _id, i.ToString());
}
return 2;
}
}
나는 끝난 일들을 되 찾을 것이지만, 나는 사전에있는 열쇠로 사용 된 이드를 풀어 놓을 것인가? :/ –
@ GrégoryL 예; 그래서 다시 찾거나, 작업에서 AsyncState를 사용할 필요가 있습니다. –
asyncState에 대해 봤습니다. 이해가 잘 된 경우 작업에 매개 변수로 전달한 ID를 다시 얻을 수 있습니다. ? 그리고이 경우 나는 ID를 다시 얻을 수 있기 때문에 더 이상 사전을 필요로하지 않습니다. –