如何异步调用一个方法?

3

我创建了一个 Windows 窗体应用程序。一旦我提交应用程序,它就会被处理。我创建了一个类库来处理应用程序并将提交的应用程序移动到不同的工作流程中。为此,我从“提交”按钮的单击事件中调用了类库。一切都正常运行,但唯一的问题是,一旦我提交应用程序并调用类库,它需要一些时间进行处理。我希望应用程序能够关闭并异步地调用类库方法。以下是代码:

private void OnPASubmit_Click(object sender, EventArgs e)
{
    if ((ApplAcct.AcctID == 0) || CheckForChanges())
    {
        UIHelper.ShowMessage("Please Save Application first");
        return;
    }
    try
    {
        if (!AOTHelper.ValidateCheckOut(ApplAcct.AcctID))
        {
            return;
        }
        WorkflowTask.PutAccountWorkflowTask(ApplAcct.AcctID, AOTHelper.FindAcctGUID(Main.objAccountGUID, Acct.AcctID), Environment.UserName, 2);
        AOTHelper.checkInAccount(ApplAcct.AcctID);
        AOTHelper.AccountToProcess(Acct.AcctID);
        UIHelper.ShowMessage("Application has been submitted for processing.");
        this.Close();
    }
    catch (Exception ex)
    {
         AOTHelper.WriteLog(ex, "Can not submit application for processing ");
    }

    // ...
}

AotHelper.AccountToProcess(Acct.AcctID)方法调用类库,我希望通过异步调用来实现,这样应用程序在提交后就不必等待处理。

我该怎么做呢?请帮忙!


几个小时前,回答了一个类似的问题 - https://dev59.com/i2TWa4cB1Zd3GeqPIfic#11033200。 - Angshuman Agarwal
7个回答

2
那么您应该使用BackgroundWorker类。

2
你可以使用BackgroundWorker线程来简化在Windows Forms中的实现。需要对密集任务进行另一个线程的处理,以防止UI冻结。在任务完成后,需要发送消息更新用户界面

当你使用BackgroundWorker类时,可以在用户界面中指示操作进度、完成和取消。例如,您可以检查后台操作是否完成取消并向用户显示消息

阅读一个简单的教程


2

有多种异步执行的方式,例如TPL、启动自己的线程(在4.5框架中使用“await”),但对于WinForms来说,最简单的方法可能是添加一个BackgroundWorker组件。您可以从工具箱中拖放一个到设计器上。

双击添加的组件,会自动创建一个方法来捕获backgroundworker的DoWork事件,您可以在其中放置您的代码。然后在提交按钮中,您只需要调用

  backgroundWorker.RunWorkerAsync();


0
有几种方法。您可以启动一个后台工作线程,调用进程并在完成时结束。 您可以创建委托并使用BeginInvoke。 您可以发送消息,服务中的监听器会接收到它并派遣一个进程来运行它。 有很多方法可以解决这个问题。
这里是一个旧但有用的MSDN参考 http://msdn.microsoft.com/en-us/magazine/cc301332.aspx

0
我希望应用程序在异步调用库方法后关闭。
如果您想在应用程序关闭之前提交数据,则需要修改处理表单即将关闭事件的代码。请注意,此事件仅在用户关闭表单时发生。如果您想要覆盖当进程被强制退出时发生的情况,则必须订阅该事件并执行类似的操作。
此外,有多种方法可以关闭进程而不触发任何这些事件。基本上,只有在进程向Windows报告其正在关闭时,此解决方案才有效。
当然,如果您的程序进程即将结束,就不应该异步提交数据。

0

你只需要在一个单独的线程上启动它。例如:

Thread thread = new Thread(new ParameterizedThreadStart(AOTHelper.AccountToProcess));
thread.Start(Acct.AcctID);

如果您要同时启动许多线程,那么您应该使用线程池。

但是,您需要小心。在单独的线程上调用的方法不能对UI进行任何操作,否则它将抛出异常。如果它需要对UI进行某些操作,则需要引用一个窗体或控件,以便可以调用该对象的Invoke方法以返回到UI线程。此外,由于它是异步发生的,因此您将无法立即在调用后显示消息框,因为这将在工作完成之前立即显示。


我将从我的窗体中调用此方法,并在调用Thread.Start()方法后关闭我的窗体。您能否告诉我这个线程将如何在内存中释放,以及何时释放? - Running Rabbit
线程将会在AOTHelper.AccountToProcess方法运行完毕后“消失”。一旦该方法执行到最后一行代码或者遇到return语句,线程将被终止。 - Steven Doggart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接