异步方法永远不会结束

本文关键字:结束 永远 异步方法 | 更新日期: 2023-09-27 17:57:49

我有一个表单,如下所示,它接受Task<T>,等待完成,然后在await之后通过关闭表单返回:

public partial class SomeForm<T> : Form
{
    public T ReturnValue { get; private set; }
    private Task<T> Task { get; set; }
    public SomeForm(string waitingText, Task<T> task)
    {
        InitializeComponent();
        ...
        PerformTask();
    }
    private async void PerformTask()
    {
        ReturnValue = await Task;
        this.Close();
    }
}

然而,尽管这个方法运行得很愉快,但它到达了ReturnValue = await Task;,然后就不再继续了。该方法将正常运行,不会被发送到该方法,也不会延迟。我有一种感觉,这与我如何使用asyncawait有关,但我是TPL等的新手

请帮助我确定上面的脚本有什么问题,以及为什么它永远不会返回。

编辑:TaskA是一个拼写错误。这是Task的方法;导入的函数。BS_Robots_LoadDrive(..)是C++函数的DllImport,它可以很好地同步工作,即使在另一个线程上(就像最后的代码片段中一样),但不能使用async参数。

    public uint LoadDisc()
    {
        uint response = ImportedFunctions.BS_Robots_LoadDrive(DriveLetters[0],
                        (int)BSRobotConstants.BIN_ID_DEFAULT,
                        (int)BSRobotConstants.POSITION_TYPE_INPUTBIN,
                        0);
        switch (response)
        {
            case BSRobotConstants.OK:
            case BSRobotConstants.OK_WITH_MESSAGE:
            case BSRobotConstants.FROMTRAY_NO_DISC:
            case BSRobotConstants.INVALID_DRIVE:
            case BSRobotConstants.INVALID_POSITION:
            case BSRobotConstants.TOTRAY_NO_DISC:
            case BSRobotConstants.TOTRAY_NOT_OPEN:
            case BSRobotConstants.FATAL_ERROR:
                break; 
            case BSRobotConstants.BUSY:
                break;
            case BSRobotConstants.TOTRAY_HAS_DISC:
                RejectDisc();
                response = LoadDisc();
                break;
        }
        return response;
    }

这项工作:

private async void PerformTask()
{
    Task.Start();
    Task.Wait();
    ReturnValue = Task.Result;
    DialogResult = DialogResult.OK;
}

但第一个代码片段没有。

异步方法永远不会结束

任务不会继续超过ReturnValue = await TaskA;,因为它不会返回。验证Task是否正在运行并且没有卡住。

要为对象构造属性实用程序async-await,请使用异步工厂方法。

请参阅:如何使用异步等待模式初始化对象

public class Form1<T> : Form
{
    public Form1(string waitingText, Task<T> task)
    {
        Task = Execute(task);
        Controls.Add(new Label { Text = waitingText });
    }
    public T ReturnValue { get { return Task.Result; } }
    public Task<T> Task { get; private set; }
    private async Task<T> Execute(Task<T> task)
    {
        var result = await task;
        Close();
        return result;
    }
}

用法:

var form = new Form1<int>("Hello", Task.Delay(1000).ContinueWith(_ => 1));
form.Show();
var returnValue = await form.Task;
Console.WriteLine(returnValue);