为了账号安全,请及时绑定邮箱和手机立即绑定

如何将元组转换为异步任务

如何将元组转换为异步任务

C#
阿晨1998 2022-11-13 15:49:15
我正在做一个小应用程序,我需要帮助,因为我不知道问题出在哪里。好久没接触C#了,在一点一点的学习,因为这一切都是我的闲暇,不再。我有以下工作正常的元组:private Tuple<int, int, int, int> CheckStatus()        {            int out = 0;            int stage = 0;            int retired = 0;            int stop = 0;            for (int i = 0; i < Dgv.Rows.Count; i++)            {                if (Dgv.Rows[i].Cells["Start"].Value != null)                {                    out = out + 1;                }                if (Dgv.Rows[i].Cells["Start"].Value != null && Dgv.Rows[i].Cells["Finnish"].Value == null)                {                    stage = stage + 1;                }                if (Dgv.Rows[i].Cells["Start"].Value != null && Dgv.Rows[i].Cells["Finnish"].Value != null)                {                    stop = stop + 1;                }            }            retired = GetRetirements();            stage = stage - retired;            return new Tuple<int, int, int,int>(out, stage, retired, stop);        }我想将它传递给异步执行 await 方法,因为现在 GetRetirements 方法是异步任务,并将代码更改为此,但我遇到了问题:private async Task<Tuple<int, int, int, int>> CheckStatus()        {            int out = 0;            int stage = 0;            int retired = 0;            int stop = 0;            for (int i = 0; i < Dgv.Rows.Count; i++)            {                if (Dgv.Rows[i].Cells["Start"].Value != null)                {                    out = out + 1;                }                if (Dgv.Rows[i].Cells["Start"].Value != null && Dgv.Rows[i].Cells["Finnish"].Value == null)                {                    stage = stage + 1;                }                if (Dgv.Rows[i].Cells["Start"].Value != null && Dgv.Rows[i].Cells["Finnish"].Value != null)                {                    stop = stop + 1;                }            }            retired = await GetRetirements();            stage = stage - retired;            return new Tuple<int, int, int,int>(out, stage, retired, stop);        }我做错了什么?这是我第一次使用 Tuple,我不知道它可能是错误的。非常感谢你。
查看完整描述

4 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

CheckStatus现在是一个异步函数。要获得您需要的结果await,您可能只想调用该函数一次。请注意如何async添加到事件处理程序GetCheckStatus并将一直流向async void事件处理程序,例如单击按钮。


private async Task GetCheckStatus()

{

    var status = await CheckStatus()

    LblOut.Text = status.Item1.ToString();

    LblStage.Text = status.Item2.ToString();

    LblRetired.Text = status.Item3.ToString();

    LblStop.Text = status.Item4.ToString();

}


查看完整回答
反对 回复 2022-11-13
?
Helenr

TA贡献1780条经验 获得超3个赞

您已将内部调用设为异步,但外部调用并未等待它。尝试类似的东西:


private async Task GetCheckStatus()

{

    var result = await CheckStatus();


    LblOut.Text = result .Item1.ToString();

    LblStage.Text = result .Item2.ToString();

    LblRetired.Text = result .Item3.ToString();

    LblStop.Text = result .Item4.ToString();

}


查看完整回答
反对 回复 2022-11-13
?
绝地无双

TA贡献1946条经验 获得超4个赞

您更改CheckStatus()为返回 a Task<>。您可能应该await这样做并像以前一样使用结果。

您还可以根据您的 UI 框架以不同的方式处理它。但归结为“这种方法现在是aysnc,就这样处理吧。”


查看完整回答
反对 回复 2022-11-13
?
莫回无

TA贡献1865条经验 获得超7个赞

原因是,您忘记在访问结果之前等待CheckStatus()结果。


以 async 结尾的异步函数名称是非常传统的。这是为了警告用户不要忘记他们正在使用 async-await,并且他们应该在访问结果之前等待返回值。


这还有一个好处是您可以同时提供普通版本和异步版本


async Task<int> GetRetirementsAsync(){...}


async Task<Tuple<int, int, int, int>> CheckStatusAsync()

{

     ...

     int retired = await GetRetirementsAsync();

     return new Tuple...

}


async Task GetCheckStatusAsync()

{

    var tuple = await CheckStatusAsync();


    // process output:

    LblOut.Text = tuple.Item1.ToString();

    LblStage.Text = tuple.Item2.ToString();

    LblRetired.Text = tuple.Item3.ToString();

    LblStop.Text = tuple.Item4.ToString();

}

可能的性能改进

您想要使用 GetRetirementsAsync 而不是非异步 GetRetirements 的原因是因为您希望进程内部的某处必须空闲地等待来自另一个进程的结果,例如查询数据库、读取文件或获取数据来自网络。


您可以使用 async await 来做其他事情,而不是无所事事地等待,直到您真正需要数据库中的结果为止。


您可以通过启动任务来执行此操作,而无需等待。该线程不会空闲地等待数据库,而是继续处理您的语句,直到您需要结果并等待任务。


private async Task<Tuple<int, int, int, int>> CheckStatus()

{

    // Get the retirements, do not await yet.

    Task<int> taskGetRetirements = GetRetirementsAsync();


    // instead of waiting idly, your thread is free to do the following:

    int out = 0;

    int stage = 0;

    int retired = 0;

    int stop = 0;

    for (int i = 0; i < Dgv.Rows.Count; i++)

    {

        ...

    }


    // now you need the retirements; await for the task to finish

    int retired = await taskGetRetirements;

    stage = stage - retired;

    return new Tuple<int, int, int,int>(out, stage, retired, stop);

}


查看完整回答
反对 回复 2022-11-13
  • 4 回答
  • 0 关注
  • 98 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信