ProgramingTip

Task.Factory.StartNew를 사용하여 메소드 매개 변수 전달

bestdevel 2020. 12. 7. 20:30
반응형

Task.Factory.StartNew를 사용하여 메소드 매개 변수 전달


다음 코드가 있습니다.

var task = Task.Factory.StartNew(CheckFiles, cancelCheckFile.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

private void CheckFiles()
{
  //Do stuff
}

이제 CheckFiles를 수정하여 정수 및 BlockingCollection 참조를 수락하고 싶습니다.

private void CheckFiles(int InputID, BlockingCollection<string> BlockingDataCollection)
{
  //Do stuff
}

위에서했던 것처럼이 작업을 시작하는 방법을 척 수없는 것입니다.

도울 수 있니?

감사합니다


가장 좋은 방법은 표시하려는 변수를 닫는 람다 식을 사용하는 것입니다.

그러나이 경우에는 루프에서 호출하는 경우주의하십시오. (당신의 변수가 "ID"이기 때문에 언급하고이 상황에서 일반적입니다.) 잘못된 범위에서 변수를 닫으면 버그가 수 있습니다. 자세한 내용 주제 에 대한 Eric Lippert의 게시물을 참조하십시오 . 일반적으로 임시로 조치합니다.

foreach(int id in myIdsToCheck)
{
    int tempId = id; // Make a temporary here!
    Task.Factory.StartNew( () => CheckFiles(tempId, theBlockingCollection),
         cancelCheckFile.Token, 
         TaskCreationOptions.LongRunning, 
         TaskScheduler.Default);
}

또한 코드가 위와 같으면 LongRunning힌트 를 사용할 때주의해야합니다 . 기본 스케줄러를 사용하면 각 작업이 대신 사용하는 대신 쓰레드 풀을 사용합니다. 많은 작업을 생성하는 경우 ThreadPool의 이점을 얻지 못하여 영향을 미칠 수 있습니다. 일반적으로 컬렉션 항목 등에서 구현되는 것이 아니라 단일 장기 실행 작업 (또는 이름)에 맞춰져 있습니다.


class Program
{
    static void Main(string[] args)
    {
        Task.Factory.StartNew(() => MyMethod("param value"));
    }

    private static void MyMethod(string p)
    {
        Console.WriteLine(p);
    }
}

단일 정수를 전달하기 위해 Reed Copsey의 답변에 동의합니다. 미래에 더 복잡한 구성을 사용하는 경우 개인적으로 모든 변수를 익명 유형으로 전달하고 싶습니다. 다음과 같이 보일 것입니다.

foreach(int id in myIdsToCheck)
{
    Task.Factory.StartNew( (Object obj) => 
        {
           var data = (dynamic)obj;
           CheckFiles(data.id, theBlockingCollection,
               cancelCheckFile.Token, 
               TaskCreationOptions.LongRunning, 
               TaskScheduler.Default);
        }, new { id = id }); // Parameter value
}

블로그 에서 자세히 알아볼 수 있습니다.


첫 번째 매개 변수를의 인스턴스로 생성합니다 Action. 예 :

var inputID = 123;
var col = new BlockingDataCollection();
var task = Task.Factory.StartNew(
    () => CheckFiles(inputID, col),
    cancelCheckFile.Token,
    TaskCreationOptions.LongRunning,
    TaskScheduler.Default);

이 시도,

        var arg = new { i = 123, j = 456 };
        var task = new TaskFactory().StartNew(new Func<dynamic, int>((argument) =>
        {
            dynamic x = argument.i * argument.j;
            return x;
        }), arg, CancellationToken.None, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
        task.Wait();
        var result = task.Result;

참고 URL : https://stackoverflow.com/questions/8127316/passing-a-method-parameter-using-task-factory-startnew

반응형