2014-04-08 2 views
1

이제는이 일이 저를 미치게합니다.작업 본문이 실행되지 않습니다

private static Task Delay(double milliseconds) 
{ 
    var tcs = new TaskCompletionSource<bool>(); 
    System.Timers.Timer timer = new System.Timers.Timer(); 
    timer.Elapsed += (obj, args) => { tcs.TrySetResult(true); }; 
    timer.Interval = milliseconds; 
    timer.AutoReset = false; 
    timer.Start(); 
    return tcs.Task; 
} 

나는 다음과 같은 코드에서 호출 : .NET FX는 4.0을 사용하여, 나는 다음과 같은 지연 메커니즘이

// delay the execution of SendKey to let the dialog show up 
var sendKeyTask = Delay(500).ContinueWith((_) => 
{ 
    // this gets executed when the dialog is visible 
    SendKeys.Send(filePath); 
}, TaskScheduler.FromCurrentSynchronizationContext()); 


MyButton.InvokeMember("click"); 
sendKeyTask.Wait(3000); //will time out after 3 seconds. 

.... 

문제는 SendKeys.Send(filePath); 라인이 실행되지 않습니다 것입니다. 내가 뭘 놓치고 있니?

+2

메인 컨텍스트에서 동기 대기 및 비동기 연속을 한 곳에서하는 것은 거의 항상 나쁜 생각입니다. 나는'sendKeyTask'와'.Wait (3000)'의 연속 사이에 교착 상태가 있다는 것을 확신 할 수 있습니다. 특히 연속이 '현재'동기화 컨텍스트에서 실행되도록 예약되었으므로 말입니다. '지연 '자체가 작동하는 것처럼 보였습니다. LINQPad에서 시도했습니다. –

답변

0

@ Patrykwwiek은 다음과 같이 말했습니다.
Wait(3000)을 제거하고 sendKeyTask이 완료된 후에 어떤 일이 일어나기를 원한다면 - 계속 진행하십시오 (또는 현재 스레드에서 실행 중일 때 sendKeyTask에서 실행하십시오).

+0

감사합니다. Shlomi. 나는'InvokeMember()'줄 다음에 무엇을 써야 하는지를 알 수 없다. 현재 함수를 떠나기 전에 sendKeyTask가 완료 될 때까지 기다려야합니다. 그 목적을 위해서'Wait()'보다 더 좋은 것이 있습니까? – dotNET

+0

먼저 비동기 작업을하는 경우 비동기로 작업하십시오. 가장 좋은 해결책은'sendKeyTask'를 리턴하는 것입니다. 그래서 메소드의 호출자는 계속 메소드를 호출 할 수 있습니다. 다른 솔루션 (더 복잡하게 생각할 수도 있습니다)은 같은 스레드에서 대기하고 실행하지 말아야합니다.하지만 SendKey는 UI 스레드에서 실행되어야합니다 ... 그래서 사각형으로 돌아갑니다 ... 그래서, 다른 해결책은 'do not do async'입니다 :'Delay' 작업을 기다리거나'Thread.Join'을 호출하고,'SendKey.Send'를 동 기적으로 호출하십시오. –

+0

간단히하려고합니다 : 당신이 비동기로 작업한다면, 당신은'sendKeyTask'를 반환 할 것입니다. 그리고 호출자는 그것을 계속할 수 있습니다. 또는 당신은 현재 스레드를 블로킹하고,'SendKey.Send'를 호출하고, 리턴하고, 그것이 끝날 때까지 기다릴 필요가 없다는 것을 의미하는 "동기화"를 수행합니다. 비동기) 호출). –

관련 문제