2013-10-15 8 views
0
public delegate string AsyncMethodCaller(int callDuration, out int threadId); 

class Program 
{ 
    static void Main(string[] args) 
    { 
     int threadId; 

     AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod); 

     IAsyncResult result = caller.BeginInvoke(3000, 
      out threadId, new AsyncCallback(Callback), null); 

     Console.WriteLine("Main thread {0} does some work.", 
      Thread.CurrentThread.ManagedThreadId); 

     string returnValue = caller.EndInvoke(out threadId, result); 

     Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", 
      threadId, returnValue); 
    } 

    static public string TestMethod(int callDuration, out int threadId) 
    { 
     Console.WriteLine("Test method begins."); 
     Thread.Sleep(callDuration); 
     threadId = Thread.CurrentThread.ManagedThreadId; 
     return String.Format("My call time was {0}.", callDuration.ToString()); 
    } 

    static void Callback(IAsyncResult result) 
    { 
     int a = 5; 
     int b = 20; 

     int c = a + b; 

     Console.WriteLine(c + Environment.NewLine); 
    } 
} 

Этот код в основном выполняет TestMethod асинхронно. Но проблема в том, что после вызова EndInvoke на вызывающем абоненте основной поток останавливается и ждет, когда TestMethod завершит работу. поэтому в основном все приложение застревает. может ли этот процесс быть асинхронным. ? Я имею в виду то, что я хочу, - это асинхронно вызывать какой-либо метод, а затем ждать обратного вызова, но если я удалю вызов EndInvoke, тогда CallBack не будет удален. Какова наилучшая практика в этой ситуации.Асинхронный вызов делегата и обратный вызов

+0

Ваш обратный вызов не попал, так как основной поток закончил. Обычно это не проблема в приложениях GUI, поскольку поток пользовательского интерфейса всегда работает. Вы должны попробовать добавить цикл, чтобы имитировать основной поток, выполняющий работу. Таким образом, он будет оставаться живым при вызове обратного вызова. –

+1

Это похоже на точный пример из [Асинхронный вызов синхронных методов] (http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx), где он говорит ** Поскольку EndInvoke может блокироваться, вы никогда не должны вызовите его из потоков, обслуживающих пользовательский интерфейс. **. Позже показано __Обращение метода обратного вызова при завершении асинхронного вызова. Однако почему вы не используете 'TPL'? – Harrison

ответ

0

Вам лучше использовать Задачи и их методы Task.Wait. http://msdn.microsoft.com/ru-ru/library/dd321424.aspx

smthing так:

var returnValue = Task<string>.Factory.StartNew(() => TestMethod()); 
+0

как насчет обратного вызова? Я хочу, чтобы callback был удален, когда TestMethod завершил выполнение. – Dimitri

+0

@Dima есть такой материал, как http://msdn.microsoft.com/ru-ru/library/dd321474.aspx попробуйте smthing вот так: 'Task tsk = new Task (TestMethod); Tasl tskCont = tsk.ContinueWith (Callback); ' –

+0

в любом случае, похоже, все о TPL –

Смежные вопросы