2016-04-18 6 views
2

С задачами можно сделать что-то вроде этого:Изменить выполнение потока текущего метода

public async Task SomeMethod() 
{ 
    // [A] Here I am in the caller thread 

    await OtherMethod().ConfigureAwait(false); 

    // [B] Here I am in some other thread 
} 

private async Task OtherMethod() 
{ 
    // Something here 
} 

Где в точках [A] и [B], вы можете быть в разных потоках. Можно ли сделать что-то похожее с асинхронным и ждать ключевых слов при выборе потока, он будет переключаться? Как так:

public void SomeMethod() 
{ 
    // [A] Here I am in the caller thread 

    ChangeThread(); 

    // [B] Here I am in some other thread 
} 

private void ChangeThread() 
{ 
    Thread thread = new Thread(???); 
    // ??? 
} 

Я знаю, что это возможно с делегатами, но можно переключиться нить внутри метода, возможно, с изменением текущего потока назад, когда метод заканчивается? Если нет, возможно ли создать что-то, используя async/await, который может изменить поток, но я контролирую, к какому потоку он переключится (например, поток пользовательского интерфейса с помощью Control.Invoke)?

+0

Что вы пытаетесь сделать и почему? Почему вы хотите «сменить поток» (нет такой вещи)? Вы столкнулись с проблемой и думаете, что «изменение потоков» - это решение? Что означает «какая нить»? Почему бы не использовать пул потоков или просто использовать 'Task.Run'? –

+0

@PanagiotisKanavos его спрашивают от чистого любопытства и не представляют собой проблему реальной жизни. –

ответ

0

То, что я всегда делаю в тех случаях, когда мне нужно изменить контекст выполнения, а затем вернуться в исходное контексте:

public async void RunWorkerAsync() 
    { 
     var result = await RetriveDataAsync(); 
    } 


public Task<Object<TItem>> RetriveResultsAsync() 
    { 
     var tokenSource = new CancellationTokenSource(); 
     var ct = tokenSource.Token; 


     var source = new TaskCompletionSource<Object<TItem>>(); 

     var task = Task.Run(() => 
     { 
      // [B] Here I am in some other thread 
      while (!ConditionToStop) 
      { 
       if (ct.IsCancellationRequested) 
       { 
        tokenSource.Cancel(); 
        ct.ThrowIfCancellationRequested(); 
       } 
      } 
     }, ct).ContinueWith(taskCont => 
     { 

      if (resultedData != null) 
      { 
       source.SetResult(resultedData); 
      } 
     }, ct); 


     bool taskCompleted = task.Wait(2000, ct); 
     if (!taskCompleted) 
     { 
      tokenSource.Cancel(); 
     } 

     return source.Task; 
    } 

В случае, если вы хотите, чтобы выполнить все в одной задаче без результатов просто передать данные и удалить taskCompleted часть и полагаться только на условие для остановки. Al ваш код будет работать в другом потоке, а после завершения будет возвращен ваш вызывающий поток. Если что-то простое без возврата - то, что вам нужно просто использовать

Task.Run(Action() => ExecuteSomething); 

в пределах метода.

+0

На самом деле это не ответ на мой вопрос. Вы просто вызываете делегата в другой поток (Task.Run), и, что еще хуже, не может выбрать Thread, он будет работать. Вместо этого он будет запущен в потоке пула потоков. –

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