C#完全运行异步方法与EndInvoke会不Application.DoEvents
我遇到了一个问题,下面的代码:C#完全运行异步方法与EndInvoke会不Application.DoEvents
private int check = 1;
private async System.Threading.Tasks.Task AsyncMethod()
{
check = 2;
await ...;
check = 3;
}
private void Load(object sender, EventArgs e)
{
var invoke = this.BeginInvoke(async x =>
{
await AsyncMethod();
});
Debug.WriteLine("1: " + check);
EndInvoke(invoke);
Debug.WriteLine("2: " + check);
Application.DoEvents();
Debug.WriteLine("3: " + check);
}
我想立即结束AsyncMethod
和完全每当我跑EndInvoke
。但是,它返回:
1: 1
2: 2
3: 3
而我期望它返回2: 3
。有没有办法做到这一点没有Application.DoEvents
(因为我想尽可能避免使用)?
编辑:经过进一步测试,似乎Application.DoEvents
在这种情况下效果最好。它甚至在AsyncMethod
包含多个await
调用时有效;所有这些都在EndInvoke
之后运行Application.DoEvents
时运行。
你在找什么是取消,取消只能在.NET中合作完成。
Here is a article来自Microsoft的文档,它解释了使您的任务/线程可取消的过程。但短版本是您需要传递给函数a CancellationToken
并在整个方法中检查以取消代码。
private int check = 1;
private async Task AsyncMethod(CancellationToken token)
{
check = 2;
await Task.Delay(5000, token); //Wait for 5 seconds or till the token is signaled.
token.ThrowIfCancellationRequested();
check = 3;
}
//Event handlers like this is the only place you are allowed to do async void
private async void Load(object sender, EventArgs e)
{
Debug.WriteLine("1: " + check);
try
{
var cts = new CancellationTokenSource();
var task = AsyncMethod(cts.Token); //Start the task
cts.Cancel();
await task; //Wait for the task to finish or throw a OperationCanceledException
Debug.WriteLine("2: " + check);
}
catch(OperationCanceledException)
{
//Do nothing
}
Debug.WriteLine("3: " + check);
}
上面会输出
1: 1
3: 2
此代码不会使用'BeginInvoke'运行'AsyncMethod',在我的程序中就是这种情况。 – Marijn
是的,但它确实调用了AsyncMethod而不立即等待它,如果你在UI线程上并且AsnycMethod表现良好,那么它会有相当类似的行为。 –
Brr中,我们编织什么靠不住的网。 BeginInvoke在UI线程上运行它的目标,但它是从已经在UI线程上运行的代码调用的。所以直到代码显式退回到调度程序循环才能执行。因此,只有在调用EndInvoke之前,才能启动*。如果您期望完成异步方法,那么它就不再是异步了,并且没有必要编写这样的代码。 –
我甚至想要使用EndInvoke的原因是因为许多数据正在使用几种方法上的BeginInvoke调用进行加载,并且生成的IAsyncResults被存储。然后对于一些操作,我必须结束使用BeginInvoke开始的所有方法,我在所有IAsyncResults上使用EndInvoke。这很有效(即它完全运行代码),除非该方法有一个等待呼叫,这在某些场合是必需的。因此,我希望它能够在这些情况下工作。 – Marijn
异步代码对于防止UI冻结很有用。这样做会让情况变得更糟。 –