2014-10-31 81 views
0

我已經讀了一些關於編寫異步代碼,但我仍然有很多問題具體關於我的編程任務。在我的Web表單應用程序中,單擊一個按鈕時,我想在另一個類中執行一個方法,該方法執行任務(將數據插入到數據庫中),同時更新屏幕的進度。例如:c# - 異步代碼,更新方法進度到頁面

btn1_OnClick(object sender, EventArgs e) 
{ 
    //call methodA asynchronously? 
} 

了methodA包含在另一個類和查詢數據庫:

public class ClassA 
{ 
    public void methodA(param) 
    { 
     //insert data into database 
     //create string that notifies the progress of the method (should be displayed on page) 

     //insert more data into database 
     //alter string to re-notify of the progress of the method (to be displayed on page) 
    } 
} 

正如你所看到的,我想,以填補這將在的形式顯示在頁面的字符串標籤隨着方法的進展。我不知道methodA是否會返回類型「void」,但我仍然把它放在那裏。我想這個任務應該異步完成,或者可以使用Web服務。那麼我如何以編程的方式來做到這一點?

編輯

我已經看了很多文章,但似乎沒有一個有效的描述過程中我的情況。他們都只是描述當長時間運行的作業開始工作時(在這種情況下,methodA)開始或結束時顯示消息。我希望方法能夠吐出一個字符串(描述它在方法中的位置,即「插入的第一組數據」...),並隨着它的進展多次顯示它。在我的情況下,這種事情對於webforms來說太過雄心勃勃......如果我要調用一個完成所有工作並收回消息的Web服務,該怎麼辦?

+0

關於「如何在網頁上顯示長時間運行的進度」有很多問題......考慮搜索自己,因爲它看起來不像任何人都知道好的重複。 – 2014-10-31 05:19:21

+0

@AlexeiLevenkov請閱讀我的第一個編輯。 – frontin 2014-10-31 15:41:31

+0

我不知道.... Myaby你應該顯示最好的「許多」文章的鏈接...我得到http://www.bing.com/search?q=c%23%20how %20to%20show%20progress%20of%20long%20running%20operation%20on%20web%20page most say say「start operation,every step should update progress in some persistent state and than poll for the progress via client script on timer」。您可以添加「長輪詢」,「websocket」或「singnalR」以搜索更快速反饋的解決方案請求。 – 2014-10-31 15:52:32

回答

2

從你的描述看來你想使用async/await模式?這在這裏是適當的。在不瞭解你的methodA所做的更多細節的情況下,不可能給你一個確切的實現。但是,下面是一個例子:

async void btn1_OnClick(object sender, EventArgs e) 
{ 
    //call methodA asynchronously 
    await MethodA(2); 
} 

public async Task MethodA(int param) 
{ 
    await Task.Run(() => InsertDataIntoDatabase()); 
    statusTextBox.Text = "first insert done"; 
    await Task.Run(() => InsertMoreDataIntoDatabase()); 
    statusTextBox.Text = "second insert done"; 
} 

上面假設你的數據庫插入方法不是異步方法。如果他們是,那麼他們不需要被包裹在任務中。如果您的方法中有多個語句來完成此操作,則爲了便於閱讀,最好將這些語句封裝在單獨的方法中。也許你甚至會重複使用第一個和第二個插入代碼。

還要注意,你可以做所有正常的事情,比如循環。所以,如果你有多個數據庫插入,但它可以寫成一個循環,這可以做到這一點:

public async Task MethodA(int param) 
{ 
    for (int i = 0; i < param; i++) 
    { 
     await Task.Run(() => InsertDataIntoDatabase(i)); 
     statusTextBox.Text = "insert #" + i + " done"; 
    } 
} 

這應該讓你開始。關於這個通用技術,有許多關於SO的問題,當然MSDN有它的文檔和教程。如果你有更多的問題,你應該從那裏開始。

+0

非常感謝。這正是我想要讓我朝着正確方向前進的原因。還有一個問題。我在單獨的類中有methodA,所以我需要以某種方式傳遞字符串,以便aspx.cs頁面可以用該字符串填充標籤? – frontin 2014-10-31 04:11:20

+1

+0請注意,雖然正確(並直接適用於* WinForms *),但該問題對問題中提到的任何Web案例(WebForms/Web服務/ ASP.Net MVC)都沒有多大幫助。 – 2014-10-31 05:16:14

+0

@RyanGray:我不知道你的不同組件是如何組織的。假設包含'methodA'的類沒有與視圖相關的邏輯,我不會添加任何。但是我認爲將這個類的事件公開給這樣的通知目的是有意義的......然後你的頁面代碼將訂閱該事件,並且以這種方式允許其他類將通知字符串傳遞給它。 – 2014-10-31 06:46:04