.net 4.5 的async-await模式是范式的变化.这真是太好了.
我一直在将一些IO重的代码移植到async-await,因为阻塞已成为过去.
相当多的人正在比较async-await和僵尸感染,我发现它相当准确.异步代码喜欢其他异步代码(您需要异步函数才能等待异步函数).因此,越来越多的函数变得异步,并且在代码库中不断增长.
将函数更改为异步是一种重复性和缺乏想象力的工作.async在声明中抛出一个关键字,包装返回值Task<>,你就完成了.令人不安的是整个过程是多么容易,并且很快文本替换脚本将为我自动化大部分"移植".
现在的问题是..如果我的所有代码都慢慢变为异步,为什么不默认将它全部变为异步?
我假设的显而易见的原因是表现.Async-await有它的开销和代码,不需要异步,最好不要.但是,如果性能是唯一的问题,那么一些聪明的优化肯定可以在不需要时自动消除开销.我已经读过关于"快速路径"优化的内容,在我看来,它应该只关注它的大部分内容.
也许这与垃圾收集者带来的范式转变相当.在GC早期,释放自己的记忆肯定更有效率.但群众仍然选择自动收集,转而采用更安全,更简单的代码,这些代码可能效率较低(甚至可能不再适用).也许这应该是这样的情况?为什么不能将所有函数都异步?
我正在尝试创建一个通用框架函数,使得任何Drawable在按下/聚焦/选择/等时都会突出显示.
我的函数接受一个Drawable并返回一个StateListDrawable,其中默认状态是Drawable本身,而状态for android.R.attr.state_pressed是相同的drawable,只需使用过滤器setColorFilter.
我的问题是我无法克隆drawable并使用过滤器创建一个单独的实例.这是我想要实现的目标:
StateListDrawable makeHighlightable(Drawable drawable)
{
StateListDrawable res = new StateListDrawable();
Drawable clone = drawable.clone(); // how do I do this??
clone.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
res.addState(new int[] {android.R.attr.state_pressed}, clone);
res.addState(new int[] { }, drawable);
return res;
}
Run Code Online (Sandbox Code Playgroud)
如果我没有克隆,那么过滤器显然适用于这两种状态.我试过玩,mutate()但它没有帮助..
有任何想法吗?
更新:
接受的答案确实克隆了一个可绘制的.这对我没有帮助,因为我的一般功能在一个不同的问题上失败了.看起来当你向StateList添加一个drawable时,它会丢失所有的过滤器.
不幸的是,Android上有很多cookie管理器.Cookie HttpURLConnection由以下人员维护,java.net.CookieManagerCookie WebView由以下人员维护android.webkit.CookieManager.这些cookie存储库是独立的,需要手动同步.
我的应用程序使用HttpURLConnections和显示WebViews(它是本机HTML混合).当然,我希望两者共享所有cookie - 所以我将在整个过程中进行透明会话.
进一步来说:
简单地说 - 我正在寻找双向同步.或者甚至更好,让它们都使用相同的cookie存储库.您可以假设它们同时处于活动状态(如在不同的选项卡上).
问题:
有没有办法让两个使用相同的cookie存储库?
如果没有,建议的做法是手动同步?什么时候我应该同步,怎么样?
相关问题:这个问题解决了类似的问题,但只实现了单向同步(HttpURLConnection - > WebView).
我最好的想法:我真的想避免手动同步,所以我试着想如何让两者都使用相同的存储库.也许我可以创建自己的扩展核心处理程序java.net.CookieManager.我将使用它将其设置为核心cookie处理程序java.net.CookieHandler.setDefault().它的实现将是android.webkit.CookieManager处理程序实例的代理(对于我只是访问webkit管理器的每个函数).
我正在绘制视图层次结构时收到java.lang.StackOverflowErrors:
at android.view.View.draw(View.java:6880)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6883)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
...
Run Code Online (Sandbox Code Playgroud)
研究指出我的视图层次结构太深,Android无法处理.实际上,使用Hierarchy Viewer,我可以看到我最长的嵌套是19个视图(!)
我的应用看起来有点像Google Play商店应用(带滑动标签).每个选项卡都是片段视图寻呼机内的嵌套片段 - 使用v4支持和HoloEverywhere.显然,这就是我的等级制度有点疯狂的原因.
我的问题:
什么是真正的堆栈大小限制?我发现无法测量UI线程的堆栈大小.网上有传闻说8KB,但有没有办法在一些样本设备上准确测量?
堆栈大小限制是否随OS ver而变化?同一层级并没有崩溃的4.0.3设备上但并崩溃上的2.3.3设备(相同的硬件).这是为什么?
除了手动优化层次结构外,还有其他方案吗?我发现无法增加UI线程的可笑小堆栈.对不起,但60-100堆栈帧限制是一个笑话.
假设#3上没有奇迹解决方案,那么应该针对核心层次结构优化的哪些建议进行推荐?
疯狂的想法 - 我注意到每个视图层添加了大约3个函数调用(View.draw,ViewGroup.dispatchDraw,ViewGroup.drawChild).也许我可以创建自己的ViewGroup实现(自定义布局),在draw()期间在堆栈上浪费更少?
我正在使用D3绘制一个力导向图,这与这个例子非常相似:http://bl.ocks.org/mbostock/1153292
我试图将箭头放在链接的中间而不是结尾.
使用attr("refX", 0)标记的帮助并不多,因为它是绝对的而不是相对于链接长度 - 我的链接有不同的长度.
我一直在谷歌上搜索周围,和我最好的想法是,以取代link.attr("marker-end", ...)与link.attr("marker-segment", ...)本示例(查找在图中间的十字).但这似乎不起作用..我猜是因为它只是SVG2草案的一部分,但我的浏览器支持较低版本?(我正在使用最新版本的Chrome btw).
如何将箭头放在链接的中间?
我正在尝试使用.NET 4.5异步和等待实现完全异步的 blob下载.
让我们假设整个blob可以立即适应内存,我们想把它保存在一个string.
码:
public async Task<string> DownloadTextAsync(ICloudBlob blob)
{
using (Stream memoryStream = new MemoryStream())
{
IAsyncResult asyncResult = blob.BeginDownloadToStream(memoryStream, null, null);
await Task.Factory.FromAsync(asyncResult, (r) => { blob.EndDownloadToStream(r); });
memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
// is this good enough?
return streamReader.ReadToEnd();
// or do we need this?
return await streamReader.ReadToEndAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccountConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("container1");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1.txt"); …Run Code Online (Sandbox Code Playgroud) 我正在实现我自己的异步HTTP处理程序,HttpTaskAsyncHandler并使用async和await来保持它完全异步.
我想直接将azure blob流式传输到客户端.确实,我可以将客户端重定向到blob URL并让它们直接下载,但我们假设我不想这样做(例如我的blob是私有的).
这是我目前的实施:
码:
public async Task<bool> DownloadToStreamAsync(ICloudBlob blob, Stream stream)
{
bool blobFound = true;
IAsyncResult asyncResult = blob.BeginDownloadToStream(stream, null, null);
await Task.Factory.FromAsync(asyncResult, (r) =>
{
try
{
blob.EndDownloadToStream(r);
}
catch (StorageException)
{
blobFound = false;
}
});
return blobFound;
}
Run Code Online (Sandbox Code Playgroud)
用法:
public override async Task ProcessRequestAsync(HttpContext context)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccountConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("container1");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1.txt");
await DownloadToStreamAsync(blockBlob, context.Response.OutputStream);
}
Run Code Online (Sandbox Code Playgroud)
这段代码确实是完全异步的,并且会在流式传输时释放我的HTTP服务器以处理其他客户端吗?(即如果我有一个服务器线程)
是否可以保持blob压缩(GZIP)并让客户端使用Content-Encoding: gzip?
更新:(从存储2.1.0.0 …
我在主UI线程中遇到 StackOverflowErrors(相关问题).我的应用针对的是Android 2.3+.在Android 4上一切都很好,但是在绘制视图布局时我在2.3.3上崩溃了.
显而易见的答案是优化我的视图布局并减少嵌套视图的数量.这是一个问题,因为大量的视图是由于我使用支持库和标签片段 - 这是推荐的方法.我不想改变我的设计并删除片段只是因为较旧的操作系统有一个小堆栈.
我正在寻找增加UI线程的堆栈大小的方法.我已经看到了这是不可能的答案,我明白清单中没有简单的设置可以做到这一点.但是,我仍然不满意没有手动解决方法.
到目前为止我最好的想法:
创建一个具有更大堆栈的新工作线程(Thread类).可以增加工作线程的堆栈大小.然后,以某种方式将此线程转换为新的UI线程.怎么样?
浏览android.app.Activity .attach(..)的Android源代码我已经看到一个活动将自己附加到UI线程.也许有一些方法来替换它附加的线程并将其更改为我的"新"UI线程
更深入到android.app.ActivityThread .startActivityNow(..),也许我将能够手动启动我的活动.创建活动后,它会自动将其自身附加到创建它的线程上.也许如果我从我的新UI线程运行它,它将工作.
如果我创建一个新的UI线程,我将不得不为它手动创建Looper.我从android.app.ActivityThread .main(..)中了解了需要创建的内容.
其他想法:
手动捕获StackOverflowError并在发生时异步移动调用,以便它们具有较小的堆栈.我在这里看到了这个好主意,但我无法让它发挥作用.
NDK线程(通过JNI)具有大堆栈.我想为了我的利益使用它们,但我认为没办法做到这一点.所有通过JNI的调用都是在自己的线程上执行的,所以我看不出如何使用NDK线程进行UI访问.
所以..
除了说这是一个非常糟糕的想法,还有其他任何建议或提示吗?你能找到做类似事情的人吗?我不能......
我正在按照本教程使用SendGrid从我的Azure Web角色发送电子邮件.
这是教程中的相关部分:
// Create credentials, specifying your user name and password.
var credentials = new NetworkCredential("username", "password");
// Create an REST transport for sending email.
var transportREST = REST.GetInstance(credentials);
// Send the email.
transportREST.Deliver(myMessage);
Run Code Online (Sandbox Code Playgroud)
在我看来,该transportREST.Deliver功能是同步的.由于它正在执行IO,我更喜欢使用新的.NET 4.5 异步,而是等待(我的所有其他代码都是完全异步的).这可能吗?是否有SendGrid的异步API或某种方式来包装现有的调用?
经验法则 - 如果您在布局中过多地使用CSS,请切换到框架.我一直在浏览那里的几十个网格/布局框架,其中大部分都集中在传统的文档网格布局上.
我的页面更像是一个SPA(单页面应用程序).它类似于桌面应用程序使用的布局.很明显,HTML不能很好地处理这个问题,需要进行大量的CSS修补.
这是我想要实现的布局示例(这应该填满整个屏幕):

请注意,固定菜单不应悬停在它们后面的滚动内容上.每个块应位于其自己的单独"框架"中 - 即左侧长列表的滚动条应显示在固定菜单下方.
我一直无法找到支持这一点的轻量级网格框架(像Sencha或Kendo UI这样的框架有点过分了).手动执行CSS非常费力.特别是如果我决定显示一个模态对话框,并在此对话框中需要类似的布局(这是最终杀了我的东西).或者,如果我决定在底部需要另一个固定菜单,那么一切都会破裂.
我甚至不确定只有CSS才有可能(我知道至少固定的底部菜单需要CSS中的一些硬编码值以缩小其后面的内容,以便滚动条不重叠).如果需要JS解决方案,并且我希望它能够处理浏览器屏幕大小调整事件 - 那么所有地狱都会破裂,因为没有简单的常见事件可以做到这一点.
我应该如何以可维护/灵活的方式处理这个问题?
评论:正如您将注意到的,我自己建议使用HTML表格来实现此布局.我真的不想接受我自己的答案.我有一种感觉,没有人会"勇敢"地提出表格(毕竟这是有争议的),我愿意为了讨论而遭受挫折
澄清:当说可维护和灵活时,我似乎不够清楚.我的意思是通过各种场景或所需的修改优雅地(即代表我的工作很少)进行布局处理.为了绝对具体,我们举一些例子:
布局不应该介意它是显示为整页还是固定模式对话框(即引导对话框).在这些场景之间切换应尽可能少地更改布局代码.
布局应该支持多种方式来描述宽度和高度(即侧栏的宽度或顶部菜单的高度).更具体地说,应支持以下大小调整方法:
正如Ian Clark最专业地指出的那样,CSS可以实现大部分开箱即用的请求.对此没有任何争论.问题仍然是原始CSS是否最简单易用,以及是否有任何可以通过框架/其他机制(如flexbox/tables)从开发人员卸载的内容.
android ×4
async-await ×4
c# ×4
azure ×3
.net-4.5 ×2
.net ×1
asynchronous ×1
cookies ×1
css ×1
d3.js ×1
drawable ×1
force-layout ×1
frameworks ×1
html ×1
http ×1
javascript ×1
layout ×1
sendgrid ×1
svg ×1