2014-01-25 54 views
0

我在寫一個應用程序,它在後臺執行很長的請求。每次請求後,我需要將結果發送到主窗體。在主線程中執行Action <>

所以,這裏是一個代碼:

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)); 
    } 

它拋出一個異常:「控制 'lastOrderId' 從一個線程訪問除了它創建的線程之外。「,可以通過添加CheckForIllegalCrossThreadCalls = false;來解決,但我認爲這是一個糟糕的體驗。如何使它正確?先謝謝你。

P.S.對不起,英文不好。

+0

檢查:http://stackoverflow.com/a/1136406/1873002 –

+0

此示例代碼你想要什麼做: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; 
} 

然後,你可以把它作爲這樣的:

相關問題