2014-10-31 34 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