2014-01-25 6 views
0

Я пишу приложение, которое выполняет очень длинные запросы на фоне. После каждого запроса мне нужно отправить результат в основную форму.Выполнение действия <> в основной теме

Итак, вот код:

Form1.cs

private async void StartButton_Click(object sender, EventArgs e) 
{ 
    await Logic.GenerateStackAsync(stackSettings, delegate(FullOrder transaction) 
      { 
       lastOrderId.Text = transaction.OrderId; 
      } 
    ); 

    MessageBox.Show("Completed!"); 
} 

Logic.cs:

public static bool GenerateStack(StackSettings stackSettings, Action<FullOrder> onOrderCreated = null) 
    { 
     for(var i = 0; i < 10; i++) 
     { 
       // long, long request, replaced with: 
       System.Threading.Thread.Sleep(10000); 
       if (onOrderCreated != null) 
       { 
        onOrderCreated.Invoke(order); 
        // tried to change it with onOrderCreated(order), no results. 
       } 
      } 

      return true; 
    } 

    public static Task<bool> GenerateStackAsync(StackSettings stackSettings, Action<FullOrder> onOrderCreated) 
    { 
     return TaskEx.Run(() => GenerateStack(stackSettings, onOrderCreated)); 
    } 

Он бросает исключение: «Control 'lastOrderId' доступ из потока кроме потока, на котором он был создан. », который можно исправить добавлением CheckForIllegalCrossThreadCalls = false;, но я думаю, что это плохой опыт. Как все исправить? Заранее спасибо.

P.S. Извините за плохой английский.

+0

проверить это: http://stackoverflow.com/a/1136406/1873002 –

+0

Этот пример кода делает именно то, что вы пытаетесь do: http://stackoverflow.com/a/21357567/1768303 – Noseratio

ответ

-1

при использовании асинхронной \ ждут у фактического начала нового потока вы делаете вы набивать там, и вы хотите, чтобы результат показать в основной теме UIThread, почему вам нужно использовать Control.Invoke

1

Во-первых, do not expose (fake-)asynchronous wrappers for your synchronous methods.

Затем, если вы хотите сообщить о ходе обновления, используйте progress update classes provided in .NET for that purpose.

public static bool GenerateStack(StackSettings stackSettings, IProgress<FullOrder> progress = null) 
{ 
    for(var i = 0; i < 10; i++) 
    { 
      // long, long request, replaced with: 
      System.Threading.Thread.Sleep(10000); 
      if (progress != null) 
      { 
       progress.Report(order); 
      } 
     } 

     return true; 
} 

Затем, вы можете назвать его как таковой:

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