2017-03-29 1 views
2

나는 너무 단순해서 내게서 나를 몰아 내게하는 뭔가에 집착했습니다.작업 속성 선언 및 대기 중

물론
Task T1 { get; set; } 

public async Task CreateAndAwaitAsync() 
{ 
    T1 = new Task(() => { 
     // time consuming work like: 
     System.Threading.Thread.Sleep(1000); 
    } 

    await T1; 
} 

람다 및 방법의 몸 (단지 예를 위해 다음과 같습니다

내가 어떤 시점에서 작업을 선언하고 나중에를 실행해야, 나는 생각 내가 말했듯이 나중에 실행해야한다.) 그러나 무엇을하더라도, await T1으로 나는 람다에 그것을 만들 수 없다! 나는 무엇이 없는가 ?? 이미 몇 년 동안 비동기식 패러다임을 사용하고 있었기 때문에 어리 석다는 생각이 들었습니다.

+1

작업을 시작하지 않았습니다. '기다리는'당신을 위해 그것을 시작하지 않습니다. 그리고 만약 당신이 그것을 시작하고 싶지 않다면 - 그냥 기다리지 말라 - 돌아온 그대로 (그리고 메소드에서 async 키워드를 제거하십시오). – Evk

+5

'Task' 생성자를 사용하지 마십시오. CPU 바운드 작업을 대기 행렬에 넣고 싶다면'T1 = Task.Run (() => ....' – JSteward

+0

@JSteward를 사용하십시오. 바로 작업이 바로 시작되기 때문에 그렇게 할 수 없습니다! 다른 작업을 시작해야합니다. 순간과 다른 곳에서 내가 선언 할 때와 장소가 다를 것입니다. – Shockwaver

답변

4

.

await은 "이 작업이 완료 될 때까지 기다린 다음 나머지 작업을 수행하십시오"를 의미합니다. 예제의 태스크가 시작되지 않았습니다. await은 작업을 시작하지 않으므로 전체 메서드가 await에 머물러 있습니다.

현재 코드를 사용하더라도 나중에 T1.Start()을 실행하면 람다가 실행되고 완료된 후 CreateAndAwaitAsync에 의해 반환 된 작업도 완료됩니다.

그렇지 않으면 - 그것은 (Task.Run)을 만들 때 바로 작업을 시작하거나하지 않고 직접 Task을 반환하거나 어떤 비동기 \ await를 :

처럼 @Evk, 당신은 T1.Start를 호출 할 필요가 말했다
public Task CreateAndAwaitAsync() 
{ 
    T1 = new Task(() => { 
     // time consuming work like: 
     System.Threading.Thread.Sleep(1000); 
    } 
    // if you need to start it somewhere, do T1.Start(); 
    return T1; 
} 
+0

완벽한 ... 그래서 어디서나 작업을 시작해야합니다. 먼저 '시작'을 호출 한 다음 '기다리는'것이 필요합니다! 알았어! 고맙습니다! – Shockwaver

+0

제공 한 코드에서 작업을 기다릴 이유가 없습니다. 메서드에서 반환하십시오. 물론 복잡한 코드가 실제로있는 경우 상황이 다를 수 있습니다. – Evk

+1

물론 내가 말했듯이, 그것은 예제를 위해서였습니다 ... 작업의 '대기'는 다른 순간에 다른 기능으로 수행 될 것입니다. – Shockwaver

0

Task 만 만들었지 만 여기에 await으로 실행되지 않습니다. Start()으로 시도하거나 T1 = Task.Run(your => lambda)을 할당하면 대기 중일 때 작동합니다.

+1

'Task.Run'을 사용하면 작업의 동작이 즉각 실행되도록 예약되어 있지만 작업을 수행 할 때만 실행해야합니다 잠시 후 '기다리는 T1'을 부르십시오. (내게 당신을 downvote하지 않았습니다.) – Shockwaver

+0

@Shockwaver 그러나 질문에 대해서는 언급하지 않았습니다. 그리고 관계없이, 당신은 즉시 그것을 기다리고 있습니다. 잠시 후에. – Servy

+0

@ Shockwaver, 그냥 AFAIK 그것은 단지 예정이지만 실행되지 않습니다. 당신이 그것을 기다리거나 (기다림()/결과) – Andrew

1

작업을 시작하지 않았습니다.

예 : 나는 더 많은 정보를 제공하기 위해 코멘트에 대답하지만, 더 나은 될 수있다 생각

public async Task DoSomething() 
{ 
    await Task.Run(() => SomeMethod()); 
} 
+0

나중에 호출하기 위해 Property에 작업을 할당해야합니다. – Shockwaver

+0

관계없이 작업을 실행하거나 시작해야합니다. –

+0

오른쪽,'await' 바로 앞에 – Shockwaver

1

()

당신이 CPU 바인딩 작업을 수행하지 않는
public async Task CreateAndAwaitAsync() 
    { 
     T1 = new Task(() => 
     { 
      // time consuming work like: 
      System.Threading.Thread.Sleep(1000); 
     }); 

     T1.Start(); 
     await T1; 
    } 
+0

Perfect! 고맙습니다! – Shockwaver

0

당신은 Task.Run를 호출 할 필요가 없지만 단지 사용할 수있는 거의 절대 비동기/await를 같은 :

public async Task DelayMe() 
    { 
    await Task.Delay(1000); 
    await MoreAsyncThings(); 
    } 

    Task T1 { get; set; } 

    public async Task CreateAndAwaitAsync() 
    { 
    T1 = DelayMe(); 
    await T1; 
    } 

업데이트 :

내가 간단한 사용과 같은 람다 제안 할 것입니다 나중에 실행하기위한 코드를 저장하려면 : 그러니까 기본적으로 호출

Func<Task> SomeWorkFactory() 
{ 
    return async() => 
    { 
    await AsyncStuff(); 
    // More Stuff 
    }; 
} 

var deferedWork = SomeWorkFactory(); 

// later somewhere else 

await deferedWork(); 

는 "SomeWorkFactory는"작업 패키지를 만들지 만 만 Func을 호출 그것을 실행하고 또한 기다리는 작업을 반환합니다.

아마 관련 :

당신이 (콜백을 기다리는 반대로 뭔가를 계산 등) CPU 바인딩 작업을 수행하는 방법을 제공하는 경우는 있지만, 호출자에게 실행 모드를 떠나 모든 비동기 서명을 제공해서는 안 . 주로 비동기 및 동시성이 다른 개념이기 때문입니다.Mads Torgersen은 여기에 대한 약간의 통찰력을 보냈습니다 : https://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B362 "라이브러리 메소드는 거짓말해서는 안됩니다."(분 42부터)

+0

'MoreAsyncThings'이 문제의 태스크에 대기 할 것이라는 것을 예언 할 수 없으므로 다른 사람이 누구와 일할 것인지를 정의한 호출자에 대기열에 넣을 수있는 독립 실행 형 엔티티 여야합니다. – Shockwaver

+1

나는 ' 나는 당신의 전반적인 문제를 완전히 이해했다고 생각합니다. 나중에 어떤 코드를 실행하고 싶다면 "full blown"작업 대신에 람다 함수로 저장하는 것이 더 낫습니다. 위의 코드 샘플을 업데이트합니다. –

+0

다시! 그 예는 단지 예일뿐입니다 !! 그 일을 시작하는 것이 었습니다! 내 소품은 이미 내가 작업을 시작하고 싶을 때 호출하는 람다이지만 가능한 한 간단하게 예제를 유지하여 내가 가진 문제점에 집중하고 내 코드를 최적화하지 않도록했다. 질문이 간단했다. 왜 내가'await'이 내가 만든 작업을 시작하지 않는가?(나는 func lambda를 컴파일하여이 작업을 얻는다는 것을 지정할 필요가 없다! 그것을 알 필요는 없다!). Evk은 거의 즉시 대답했다 : "당신이 어리석은 원숭이이기 때문에 :'기다리는'마술처럼'Task'를 시작하지 않아야합니다.'먼저 시작하십시오! '. 좋은! – Shockwaver