请考虑以下Windows窗体代码:
private async void UpdateUIControlClicked(object sender, EventArgs e)
{
this.txtUIControl.Text = "I will be updated after 2nd await - i hope!";
await Task.Delay(5000).ConfigureAwait(continueOnCapturedContext: false);
this.txtUIControl.Text = "I am updated now.";
}
Run Code Online (Sandbox Code Playgroud)
这里异常是在第3行引发的,因为在等待代码在非UI线程上执行之后.ConfigureAwait(false)有用吗?
我有一个WPF GUI,我想按下一个按钮来启动一个长任务,而不会在任务期间冻结窗口.当任务正在运行时,我想获得有关进度的报告,我想在我选择的任何时候添加另一个按钮来停止任务.
我无法想出使用async/await/task的正确方法.我不能包括我尝试的所有东西,但这就是我现在拥有的东西.
一个WPF窗口类:
public partial class MainWindow : Window
{
readonly otherClass _burnBabyBurn = new OtherClass();
internal bool StopWorking = false;
//A button method to start the long running method
private async void Button_Click_3(object sender, RoutedEventArgs e)
{
Task burnTheBaby = _burnBabyBurn.ExecuteLongProcedureAsync(this, intParam1, intParam2, intParam3);
await burnTheBaby;
}
//A button Method to interrupt and stop the long running method
private void StopButton_Click(object sender, RoutedEventArgs e)
{
StopWorking = true;
}
//A method to allow the worker method to call …Run Code Online (Sandbox Code Playgroud) 在Async/Await FAQ中,Stephen Toub说:
一个awaitable是任何类型的,它公开
GetAwaiter它返回一个有效的方法awaiter.
...
一个awaiter是任何从一个返回类型awaitable的GetAwaiter方法和符合特定的图案.
因此,为了成为awaiter,类型应该:
INotifyCompletion接口.IsCompleted.GetResult返回void或无参数的方法TResult.(我现在忽略ICriticalNotifyCompletion了.)
我知道我提到的页面有一个示例,显示编译器如何转换等待操作,但我很难理解.
当我等待的awaitable,
IsCompleted检查?我应该在哪里设置它?OnCompleted召唤?OnCompleted?OnCompleted和Task.Run(continuation)在不同示例中使用的示例,我应该选择哪个以及为什么?试图使用新的C#5异步模型,令我惊讶的AspNetSynchronizationContext是内部类(以及AspNetSynchronizationContextBase基础).因而无证.但是,在ASP.NET代码中使用async/await功能时,了解它的作用至关重要.我是否正确,它确实保证您的延续将与HttpContext.Current原始呼叫者相同?它不保证continuation将在与调用者相同的线程上执行吗?
如果后一个假设不正确并且我得到原始线程,我可以确保在continuation中获得相同的线程上下文吗?我的意思是与线程和线程本地存储相关的主体/文化?这很重要,因为ASP.NET本地化依赖于线程的文化,而我的应用程序依赖于.NET角色安全模型(线程的主体).
对于在Unity中专门研究此难题的人来说,这很重要,
请确保看到我问的另一个问题,它提出了相关的关键问题:
对于C#专家,Unity是单线程的1
在另一个线程上进行计算等是很常见的。
当您在另一个线程上执行某些操作时,您经常会使用async / wait,因为,所有优秀的C#程序员都说这是简单的方法!
void TankExplodes() {
ShowExplosion(); .. ordinary Unity thread
SoundEffects(); .. ordinary Unity thread
SendExplosionInfo(); .. it goes to another thread. let's use 'async/wait'
}
using System.Net.WebSockets;
async void SendExplosionInfo() {
cws = new ClientWebSocket();
try {
await cws.ConnectAsync(u, CancellationToken.None);
...
Scene.NewsFromServer("done!"); // class function to go back to main tread
}
catch (Exception e) { ... }
}
Run Code Online (Sandbox Code Playgroud)
好的,因此,当您执行此操作时,在Unity / C#中以更常规的方式启动线程时,您将“照常做” (例如,使用Thread或其他方法,或者让本机插件执行它,或使用OS或其他方法)可能是这样)。
一切都很好。
作为一个la脚的Unity程序员,他只知道足够的C#来结束一天,我一直认为 …
我读过埃里克利珀的文章有关async,而约困惑的人曾与async关键字.他说 :
it(
async)表示"此方法包含涉及等待异步操作的控制流,因此将由编译器重写为连续传递样式,以确保异步操作可以在正确的位置恢复此方法." 异步方法的全部意义你尽可能地留在当前的线程上
我不明白这一点.如果我执行一个异步方法(Task)并且它运行,它肯定会在另一个线程上运行.
此外,如果我写的方法使用await,(IMHO)它释放正常的控制流,和代码重构 相似" ContinueWith"后,在另一个线程.
我用(控制台)测试了它:
/*1*/ public void StartChain()
/*2*/ {
/*3*/ var a = FuncA();
/*4*/ Console.WriteLine(a.Result);
/*5*/ }
/*6*/
/*7*/ public async Task < int > FuncA()
/*8*/ {
/*9*/ Console.WriteLine("A--" + Thread.CurrentThread.ManagedThreadId);
/*10*/ var t = await FuncB();
/*11*/ Console.WriteLine("B--" + Thread.CurrentThread.ManagedThreadId);
/*12*/ return t;
/*13*/ }
/*14*/
/*15*/ public async Task < int > …Run Code Online (Sandbox Code Playgroud)