在哪里停止使用异步/await关键字? [英] Where to stop using async /await keywords?

查看:211
本文介绍了在哪里停止使用异步/await关键字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的DB2/400,我有一个简单的心跳方法:

I have a simple heartbeat method for my DB2/400:

public bool CheckConnection()
        {
            try
            {
                using (OleDbConnection db = new OleDbConnection( this.conString ))
                {
                    OleDbCommand cmd = new OleDbCommand();
                    cmd.CommandText = "select 1 from sysibm.sysdummy1";
                    cmd.Connection = db;
                    db.Open();
                    cmd.ExecuteReader();
                    db.Close();
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

我想在我的应用程序运行时使用它,当然我也不想保留其余表单的执行.

I want to use this when my application runs ,and of course i dont want to hold the execution of the rest of the form.

我在表单中的主要方法:

My main method in my form:

public FrmMain()
    {
        InitializeComponent();
        PrepareFormTexts();
        PrepareFormData();
        PrepareStateClass();
        CheckDbConnection();
        //Initialize Data Access for AS400
        Dal = JDE8Dal.Instance;
        Dal.conString = Properties.Settings.Default.conAS400;
        //Initialize Icons
        picCon.Image = Properties.Resources.ledGreen;
        picStatus.Image = Properties.Resources.ledGreen;
        // Load recording from file if they exist
        PrepareRecordings(AppState.DataFileName,'|');
    }

CheckDbConnection方法:

CheckDbConnection method:

    private async Task<bool> CheckDbConnection()
    {
        return await Task.Factory .StartNew(() => Dal.CheckConnection());
    }

我认为它运行正常,但是我得到警告

I think it runs fine but i get a warning

警告1由于未等待此调用,因此在调用完成之前将继续执行当前方法.考虑将"await"运算符应用于调用结果.

Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

我应该忽略它吗?我应该在主要方法中放入异步信号吗?

Should i ignore it? should i put async in main method?

更新:在下面讨论之后,我发现由于我使用的是.NET 4.0异步包,因此我无法使dal方法成为非阻塞性的.我唯一能做的就是使用async/await + task.factory.startnew,以便在dal在后台运行时保持我的应用正常运行.

UPDATE: After discussing below i found out that since i am using async package for .NET 4.0 i cant really make my dal methods non-blocking. the only thing i can do is to use the async/await + task.factory.startnew in order to keep my app working while dal works on the background.

以下代码:

public FrmMain()
    {
        InitializeComponent();
        Load += FormLoadInit;
    }

    private async void FormLoadInit(object sender, EventArgs e)
    {
        PrepareFormTexts();
        PrepareFormData();
        PrepareStateClass();
        txtLot.Select();
        //Initialize Data Access for AS400
        Dal = JDE8Dal.Instance;
        Dal.conString = Properties.Settings.Default.conAS400;
        // Load recording from file if they exist
        PrepareRecordings(AppState.DataFileName, '|');
        bool cn = await Task.Factory.StartNew(() => Dal.CheckConnection());
        //Initialize Icons
        picCon.Image = cn ? Resources.ledGreen : Resources.ledRed;
        picStatus.Image = Properties.Resources.ledGreen;

    }

推荐答案

警告告诉您的是,您实际上在点火,然后忘记了此异步任务.您永远不会真正使用该操作的结果,甚至也不会存储Task本身,以允许将来的任何代码都可以依赖该结果(甚至不知道何时完成).

What the warning is telling you is that you are effectively firing and then forgetting this asynchronous task. You never actually use the results of the operation, nor do you even store the Task itself to allow any future code to rely on it's result (or even knowing when it finished).

这不会破坏任何内容,但也没有太大帮助.您也可以不调用该方法.现在,在您的情况下,这只是一个虚拟列表,因此您需要问自己要测试的内容.您是否要在表单上显示一些虚拟值以作为概念证明?如果是这样,您的代码将需要进行一些更改才能到达.

This won't break anything, but it's not really helpful either. You may as well just not call the method. Now, in your case this is just a dummy list, so you need to ask yourself what you're trying to test. Do you want to display some dummy value on the form just as a proof of concept? If so, you're code will need a few changes to get there.

要实际使用查询结果,您需要对其进行await,并且您不能在构造函数中执行此操作.您需要将代码移至Form Load事件处理程序并将该处理程序标记为async,以便可以在其中进行await

To actually use the results of the query you'll need to await it, and you can't do that from within a constructor. You'll want to move the code to the Form Load event handler and mark the handler as async so that you can await within it.

您遇到的另一个问题是,要创建异步方法,您要启动一个新任务,该任务将在线程池中运行,然后让其执行阻塞方法.使用异步/等待模型的主要优点是您不需要这样做.您应该使用直接向您提供Task<T>作为其返回值且不会阻塞的数据库查询方法.然后,您可以await处理这些任务(或仅返回它们),以使您的应用程序在等待时不会阻塞任何线程.

Another issue you have is that, to create your async method, you're starting a new task that will run in a thread pool and then having it perform blocking methods. The primary advantage of using the async/await model is that you don't need to do that. You should be using database querying methods that directly give you a Task<T> as their return value and don't block. You can then await on those tasks (or just return them) such that your application has no threads being blocked while you wait.

您的CheckConnection方法应如下所示:

public async Task<bool> CheckConnection()
{
    try
    {
        using (OleDbConnection db = new OleDbConnection(this.conString))
        {
            OleDbCommand cmd = new OleDbCommand();
            cmd.CommandText = "select 1 from sysibm.sysdummy1";
            cmd.Connection = db;
            db.Open();
            await cmd.ExecuteReaderAsync();
            return true;
        }
    }
    catch (Exception)
    {
        return false;
    }
}

CheckDbConnection然后不需要存在.无需将CheckConnection包装在Task中,因为它已经返回了任务.

CheckDbConnection then doesn't need to exist. There's no need to wrap CheckConnection in a Task because it already returns a task.

这篇关于在哪里停止使用异步/await关键字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆