我正在观看异步的禅:最佳性能的最佳实践和Stephen Toub开始谈论任务缓存,而不是缓存任务作业的结果,你自己缓存任务.据我所知,为每项工作开始一项新任务是昂贵的,应该尽量减少.在28:00左右,他展示了这种方法:
private static ConcurrentDictionary<string, string> s_urlToContents;
public static async Task<string> GetContentsAsync(string url)
{
string contents;
if(!s_urlToContents.TryGetValue(url, out contents))
{
var response = new HttpClient().GetAsync(url);
contents = response.EnsureSuccessStatusCode().Content.ReadAsString();
s_urlToContents.TryAdd(url, contents);
}
return contents;
}
Run Code Online (Sandbox Code Playgroud)
首先看起来像是一个很好的思考方法,你缓存结果,我没有考虑缓存获取内容的工作.
而且他展示了这种方法:
private static ConcurrentDictionary<string, Task<string>> s_urlToContents;
public static Task<string> GetContentsAsync(string url)
{
Task<string> contents;
if(!s_urlToContents.TryGetValue(url, out contents))
{
contents = GetContentsAsync(url);
contents.ContinueWith(t => s_urlToContents.TryAdd(url, t); },
TaskContinuationOptions.OnlyOnRanToCompletion |
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}
return contents;
}
private static async Task<string> GetContentsAsync(string url)
{ …Run Code Online (Sandbox Code Playgroud) 显然TaskFactory.StartNew,.NET 4.0中的方法旨在替代ThreadPool.QueueUserWorkItem(根据这篇文章,无论如何).我的问题很简单:有谁知道为什么?
是否TaskFactory.StartNew有更好的表现?它使用更少的内存吗?或者它主要是为了Task班级提供的附加功能?在后一种情况下,StartNew可能会有比较差的表现QueueUserWorkItem吗?
在我看来,StartNew实际上可能会使用更多的内存QueueUserWorkItem,因为它会Task在每次调用时返回一个对象,我希望这会导致更多的内存分配.
无论如何,我很想知道哪种更适合高性能场景.
有没有办法在不使用环境变量的情况下将命名参数传递给Rake任务?
我知道Rake任务可以接受两种格式的参数:
环境变量
$ rake my_task foo=bar
Run Code Online (Sandbox Code Playgroud)
这将创建名称的环境变量foo和值bar可在Rake任务进行访问my_task的ENV['foo'].
耙任务参数
$ rake my_task['foo','bar']
Run Code Online (Sandbox Code Playgroud)
此传递的值foo与bar前两个任务参数(如果它们被定义).如果my_task被定义为:
task :my_task, :argument_1, :argument_2
Run Code Online (Sandbox Code Playgroud)
然后argument_1会有价值foo,argument_2并具有价值bar.
由于C#的Task是一个类,你显然无法将其转换Task<TDerived>为a Task<TBase>.
但是,你可以这样做:
public async Task<TBase> Run() {
return await MethodThatReturnsDerivedTask();
}
Run Code Online (Sandbox Code Playgroud)
是否有一个静态任务方法我可以调用来获取一个Task<TDerived>基本上只指向底层任务并转换结果的实例?我喜欢这样的东西:
public Task<TBase> Run() {
return Task.FromDerived(MethodThatReturnsDerivedTask());
}
Run Code Online (Sandbox Code Playgroud)
这种方法存在吗?是否仅为此目的使用异步方法有任何开销?
我想异步制作一个Web服务请求.我在这里称呼它:
List<Item> list = GetListAsync();
Run Code Online (Sandbox Code Playgroud)
这是我的函数的声明,它应该返回一个列表:
private async Task<List<Item>> GetListAsync(){
List<Item> list = await Task.Run(() => manager.GetList());
return list;
}
Run Code Online (Sandbox Code Playgroud)
如果我想编译我得到以下错误
Cannot implicitely convert type System.Threading.Tasks.Task<System.Collections.Generic.List<Item>> to System.Collections.Generic.List<Item>
Run Code Online (Sandbox Code Playgroud)
据我所知,如果我使用async修饰符,结果将自动包含在Task中.我认为这不会发生,因为我使用Task.Run.如果我删除了Task.Run(() =>我得到的部分
无法等待System.Collections.Generic.List表达式
我想我还没有完全理解async/await方法.我做错了什么?
而不是像这样单独运行每个rake任务:
rake db:drop
rake db:create
rake db:migrate
rake db:load
Run Code Online (Sandbox Code Playgroud)
我想运行一个完成所有操作的rake任务.
这就是我对rakefile的看法:
desc 'This rebuilds development db'
namespace :rebuild_dev do
Rake::Task["db:drop"].execute
Rake::Task["db:create"].execute
Rake::Task["db:migrate"].execute
Rake::Task["db:load"].execute
end
Run Code Online (Sandbox Code Playgroud)
我运行它时上面的方法不起作用.
Web和Stack Overflow中有很多地方不鼓励改变ThreadPool线程或TPL 任务的优先级.特别是:
"你无法控制线程池线程的状态和优先级."
"运行时管理线程池.您无法控制线程的调度,也无法更改线程的优先级."
"你不应该改变PoolThread的文化或优先级......或者就像你没有画出或重新装修租赁汽车一样."
"在某些情况下,创建和管理自己的线程而不是使用线程池线程是合适的:(例如...)您需要一个线程具有特定的优先级."
"ThreadPool中的每个线程都以默认优先级运行,而更改ThreadPriority的代码无效."
但是,这样做很简单,调试器显示更改似乎确实存在(只要值可以回读).
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
Run Code Online (Sandbox Code Playgroud)
所以问题是,这个禁忌的具体原因是什么?
我怀疑:这样做会扰乱游泳池的微妙负载平衡假设.但这并不能解释为什么有些消息来源说你无法改变它.
我想知道是否可能(以及如何)在特定时间启动我的应用程序,就像闹钟在特定时间熄灭.假设我希望我的应用程序在早上8点启动,这是可行的吗?
熟悉的场景:我有一个Main活动,在按下按钮时启动游戏活动.如果用户按下HOME,然后再次启动我的应用程序,则应该显示Game活动,这是他在使用应用程序时最后所做的事情.
但是,相反的是他再次获得Main活动.我觉得Android正在创建另一个 MainActivity实例并将其添加到该应用程序的堆栈中,而不是仅仅选择顶部的任何内容,因为如果我在重新启动应用程序后按BACK,我会进入游戏活动!并且每次调用Main.onCreate方法,而不是调用GameActivity.onResume.
我AndroidManifest.xml几乎是'骨头':
<activity android:name="MainActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="GameActivity" android:label="@string/app_name">
</activity>
Run Code Online (Sandbox Code Playgroud)
如你所见,没有什么太花哨的.
这就是新活动的推出方式,也非常简单:
Intent intent = new Intent(this, GameActivity.class);
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)
从理论上说,这应该在Android中起到"开箱即用"的作用,因为一个非常相似的问题的答案是:在Android中维护标准应用程序活动后备堆栈状态(使用singleTask启动模式),但事实并非如此.
我一直在阅读和重读有关活动和任务和堆栈的文档,并在SO中浏览所有相关的答案,但我不明白为什么这么简单的设置不能按预期工作.
.NET 4有一个Class - Task.这很有趣,我想开始使用它.例如,我想创建一个非常简单的基于任务的文件下载器,可以在每次下载时取消.任何人都可以向我介绍一些这样做的示例代码吗?我想有一个正在运行的任务列表,并希望能够取消它们中的任何一个.
PS Code示例可能无法正常运行我只想知道如何以最佳方式使用这些东西.
task ×10
c# ×4
.net ×3
async-await ×3
android ×2
rake ×2
threadpool ×2
alarm ×1
arguments ×1
asynchronous ×1
caching ×1
list ×1
performance ×1
ruby ×1
stack ×1
taskfactory ×1