C# 在WPF调度程序调用中等待
当在发送给调度程序的委托中醒来时,确保错误处理的最佳解决方案是什么 简而言之:我需要在将计算解析为Foo后返回一个数字。该计算非常缓慢,必须在UI线程上完成。计算必须作为C# 在WPF调度程序调用中等待,c#,wpf,async-await,C#,Wpf,Async Await,当在发送给调度程序的委托中醒来时,确保错误处理的最佳解决方案是什么 简而言之:我需要在将计算解析为Foo后返回一个数字。该计算非常缓慢,必须在UI线程上完成。计算必须作为任务交给另一个类 我能想出的唯一解决办法是打电话给FooWithAtask____;3,但我甚至不确定 public class Foo { public void CallMeWithATaskThatIsFinishedWhenTheUIIsUpdated(Task<string> task) { } }
任务
交给另一个类
我能想出的唯一解决办法是打电话给FooWithAtask____;3,但我甚至不确定
public class Foo
{
public void CallMeWithATaskThatIsFinishedWhenTheUIIsUpdated(Task<string> task) { }
}
// CallFooWithATask___ is invoked from unknown thread. Can't wait for GetWithSideEffects on calling thread
public class SomeClass
{
private TextBox textBox;
public int CallFooWithATask___1(Foo foo)
{
// not good - async void -> no error handling
var tcs = new TaskCompletionSource<string>();
Dispatcher.CurrentDispatcher.BeginInvoke(async () =>
{
var a = await GetWithSideEffects();
textBox.Text = a;
tcs.SetResult(a);
});
// quite fast - probally put it in a queue and returns
foo.CallMeWithATaskThatIsFinishedWhenTheUIIsUpdated(tcs.Task);
return 1;
}
public async Task<int> CallFooWithATask___2(Foo foo)
{
// not good - still async void -> no error handling .. when is foo actually called? I assume when hitting the inner await'ish?
var task = await Dispatcher.CurrentDispatcher.InvokeAsync(async () =>
{
var a = await GetWithSideEffects();
textBox.Text = a;
return a;
});
// quite fast - probally put it in a queue and returns
foo.CallMeWithATaskThatIsFinishedWhenTheUIIsUpdated(task);
return 1;
}
public int CallFooWithATask___3(Foo foo)
{
// what is the elegant solution - probally not this?
var tcs = new TaskCompletionSource<string>();
Dispatcher.CurrentDispatcher.BeginInvoke(async () =>
{
try
{
var a = await GetWithSideEffects();
textBox.Text = a;
tcs.SetResult(a);
}
catch (Exception ex) { tcs.SetException(ex); }
});
// quite fast - probally put it in a queue and returns
foo.CallMeWithATaskThatIsFinishedWhenTheUIIsUpdated(tcs.Task);
return 1;
}
// this might trigger ui updates and is very slow ..
private Task<string> GetWithSideEffects()=> Task.FromResult("42");
}
公共类Foo
{
更新UIS(任务){}时完成的任务的公共void调用MEWITH
}
//从未知线程调用CallFooWithATask__;。无法在调用线程上等待GetWithSideEffects
公共类
{
私人文本框文本框;
公共int呼叫Fooowithatask___;1(Foo-Foo)
{
//不好-异步无效->无错误处理
var tcs=new TaskCompletionSource();
Dispatcher.CurrentDispatcher.BeginInvoke(异步()=>
{
var a=等待GetWithSideEffects();
Text=a;
tcs.SetResult(a);
});
//相当快-很可能将其放入队列并返回
更新UI时已完成的任务(tcs.Task)的foo.callMeWith;
返回1;
}
公共异步任务调用FooWithAtask__2(Foo-Foo)
{
//不好-仍然异步void->no error handling..foo实际上是什么时候调用的?我假设是在命中内部wait'ish时?
var task=await Dispatcher.CurrentDispatcher.InvokeAsync(异步()=>
{
var a=等待GetWithSideEffects();
Text=a;
返回a;
});
//相当快-很可能将其放入队列并返回
foo.callmewith任务,该任务在UI更新时完成(任务);
返回1;
}
公共int呼叫Fooowithatask___;3(Foo-Foo)
{
//优雅的解决方案是什么?可能不是这个?
var tcs=new TaskCompletionSource();
Dispatcher.CurrentDispatcher.BeginInvoke(异步()=>
{
尝试
{
var a=等待GetWithSideEffects();
Text=a;
tcs.SetResult(a);
}
catch(Exception ex){tcs.SetException(ex);}
});
//相当快-很可能将其放入队列并返回
更新UI时已完成的任务(tcs.Task)的foo.callMeWith;
返回1;
}
//这可能会触发ui更新,速度非常慢。。
私有任务GetWithSideEffects()=>Task.FromResult(“42”);
}
你很接近了。只需在方法或Func
中提取异步代码,以避免以async void
结尾:
Func<Task<string>> func = async () =>
{
var a = await GetWithSideEffects();
return a;
};
您的问题是什么?当在传递给调度程序的委托中醒来时,确保错误处理的最佳解决方案是什么。通常,我建议对代码进行结构化,以便UI调用逻辑,而不是调用UI的逻辑。UI不应该向逻辑提供服务。如果逻辑需要一个服务,那么为它定义一个接口,然后UI可以实现该接口,如果绝对必要,可以使用
SynchronizationContext
。
var task = Dispatcher.InvokeAsync(func).Task.Unwrap();
foo.CallMeWithATaskThatIsFinishedWhenTheUIIsUpdated(task);