异步方法永远不会结束
本文关键字:结束 永远 异步方法 | 更新日期: 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;
,然后就不再继续了。该方法将正常运行,不会被发送到该方法,也不会延迟。我有一种感觉,这与我如何使用async
和await
有关,但我是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);