异步方法已经完成了

时间:2014-04-10 14:51:20

标签: c# asynchronous task-parallel-library async-await

我有一个表单,如下所示,接受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的方法; ImportedFunctions。 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;
}

但第一段代码片段没有。

1 个答案:

答案 0 :(得分:2)

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

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

请参阅:How to initialize an object using async-await pattern

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);