如何使用任务有条不紊地运行代码
我有一个负责检索资源的课程,这些课程也会对它们进行快速访问。 该类公开了一种用于检索资源的异步方法:
public Task GetResourceAsync(string resourceName) { return Task.Factory.StartNew(() => { // look in cache // if not found, get from disk // return resource }); }
然后客户端代码如下所示:
myResourceProvider.GetResourceAsync("myResource") .ContinueWith(t => Console.WriteLine("Got resource " + t.Result.ToString()));
这样,始终使用后台线程。 但是,如果在缓存中找到对象,我不希望代码异步运行。 如果在缓存中找到它,我想立即返回资源而不必使用另一个线程。
谢谢。
.NET 4.5具有Task.FromResult
,它允许您返回Task
,但它不是在线程池线程上运行委托,而是显式设置任务的返回值。
所以在你的代码的上下文中:
public Task
如果您仍在使用.NET 4.0,则可以使用TaskCompletionSource
执行相同的操作:
var tcs = new TaskCompletionSource(); tcs.SetResult(...item from cache...); return tcs.Task;
如果您有UI连接线程,请小心。
在WPF中,非常重要的是,在UI线程上使用Task.Run(例如,按钮单击事件处理程序),以避免UI问题,并在后台线程上运行代码。
为什么? Task.Run默认情况下是一个包装Task.Factory.StartNew的包装器,带有TaskScheduler.Default参数,而不是TaskScheduler.Current。
所以仅仅调用这样的异步方法还不够,因为这是在UI线程上运行并冻结它: await SomeTaskAsync();
而不是它你应该在Task.Run中调用它:
-
Task.Run(async() => await SomeTaskAsync());
或者在Task.Run中使用syncron方法:
-
Task.Run(() => SomeTask());
- CorrelationManager.LogicalOperationStack是否与Parallel.For,Tasks,Threads等兼容
- 从C#中的另一个表单听主表格中的事件
- .NET 4.0中新的“动态”变量类型是否解决了CLR中的单/多方法调度问题?
- 如何在ASP .NET MVC中将对象列表与用户(Account)关联
- 使用SignalR时,mscorlib.dll中出现“System.AggregateException”
- Windows窗体在表格布局面板中重新排列元素
- C#.Net 4.5 PropertyGrid:如何隐藏属性
- unlockbits,lockbits和try-finally
- GC和IDispose如何在C#中工作?