我已经阅读了一些关于编写异步代码的内容,但我仍然有很多关于编程任务的问题。在我的Web表单应用程序中,单击按钮,我想在另一个执行任务(将数据插入到数据库)的类中运行一个方法,同时更新屏幕上的进度。例如:
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 :(得分: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也有它的文档和教程。如果您有更多问题,请从那里开始。