C# 任务。在循环内等待未按预期操作
我有一个等待异步线程返回的类。我要做的是启动一个while循环,并每秒检查它在哪里C# 任务。在循环内等待未按预期操作,c#,async-await,C#,Async Await,我有一个等待异步线程返回的类。我要做的是启动一个while循环,并每秒检查它在哪里 public class AsychronousThingy { public bool IsComplete{get;private set;} public string Result {get;private set;} public void StartDoingThings(){ IsComplete = false; // kick of an async
public class AsychronousThingy
{
public bool IsComplete{get;private set;}
public string Result {get;private set;}
public void StartDoingThings(){
IsComplete = false;
// kick of an asynchronous thread to do stuff...
}
private void OnComplete(){
IsComplete = true;
Result = "magical result";
}
}
public class ActionExecutor{
public async Task<CustomThingyTaskResult> DoStuff(){
var thing = new AsychronousThingy();
thing.StartDoingThings();
// this returns instantly...?
while(!thing.IsComplete){
await Task.Delay(1000);
}
// do stuff once the 'thing' is complete.
return new CustomThingyTaskResult(thing.Result);
}
}
class Program{
public static void Main(){
var exec = new ActionExecutor();
var returnValue = await exec.DoStuff();
}
}
公共类异步
{
public bool IsComplete{get;private set;}
公共字符串结果{get;private set;}
公共无效开始思考(){
IsComplete=假;
//一个异步线程的踢做的东西。。。
}
私有void OnComplete(){
IsComplete=true;
Result=“神奇的结果”;
}
}
公共类诉讼执行人{
公共异步任务DoStuff(){
var thing=新的异步thingy();
开始思考;
//这个马上就回来了。。。?
而(!thing.IsComplete){
等待任务。延迟(1000);
}
//一旦“事情”完成,就去做。
返回新CustomThingyTaskResult(thing.Result);
}
}
班级计划{
公共静态void Main(){
var exec=新的ActionExecutor();
var returnValue=wait exec.DoStuff();
}
}
我不确定它为什么会立即返回。这是一个问题吗?你不能在循环中使用Task.Delay吗?奇怪
我确信这是在它完成之前返回的,就像我控制台时一样。从异步类的OnComplete事件中写入线实际上是在我的主方法完成之后完成的。因为DoStuff()
是异步的,所以调用时它会异步完成。这解释了为什么异步操作完成时,main
方法已经返回。但是,由于DoStuff
返回void
,因此您不能像通常那样等待它。您可以将返回类型更改为Task
,然后等待它
在循环中等待没有什么错,只是使用事件(或其他同步机制)更有效。另外,AsynchronousThingy
也可以用任务来表示:-)因为DoStuff()
是异步的,所以调用时它是异步完成的。这解释了为什么异步操作完成时,main
方法已经返回。但是,由于DoStuff
返回void
,因此您不能像通常那样等待它。您可以将返回类型更改为Task
,然后等待它
在循环中等待没有什么错,只是使用事件(或其他同步机制)更有效。另外,AsynchronousThingy
也可以用任务来表述:-)您的Main()
函数是void
。因此,在第一次点击实际的async
操作(在您的示例中是wait Task.Delay(1000)
)后,它将控制权返回给调用者。
因此,您可以按如下方式更改Main()
函数的签名:
public static async Task Main() {...}
然后等待它
或者,您也可以不在其上使用async
关键字,而使用旧的等待/结果:
public static void Main()
{
...
var returnValue = exec.DoStuff().Result;
// Or, if there is a SynchronizationContext
returnValue = Task.Run(() => exec.DoStuff()).Result; // This may prevent dead locks that can occur in previous line
}
您的Main()
函数是void
。因此,在第一次点击实际的async
操作(在您的示例中是wait Task.Delay(1000)
)后,它将控制权返回给调用者。
因此,您可以按如下方式更改Main()
函数的签名:
public static async Task Main() {...}
然后等待它
或者,您也可以不在其上使用async
关键字,而使用旧的等待/结果:
public static void Main()
{
...
var returnValue = exec.DoStuff().Result;
// Or, if there is a SynchronizationContext
returnValue = Task.Run(() => exec.DoStuff()).Result; // This may prevent dead locks that can occur in previous line
}
您应该改为使用任务
-无效
。您应该改为使用任务
-无效
DoStuff
应该返回一个任务
向它道歉。。。非常糟糕的伪示例。已更新。您更新的代码无法编译,因为wait
不能在Main
中使用DoStuff
应返回任务
对此表示歉意。。。非常糟糕的伪示例。更新。您更新的代码无法编译,因为wait
不能在Main
中使用。这实际上接近正确答案-我的示例是一个伪示例;但主要问题是父类的父类(即上面我的示例中的main
方法)没有作为任务运行。解决了这个问题,并使方法在等待
时保持控制。这实际上接近正确答案-我的示例是一个伪示例;但主要问题是父类的父类(即上面我的示例中的main
方法)没有作为任务运行。修复此问题解决了此问题,并使该方法在等待
时保持控制。