采取以下无用的计划:
class Program
{
static void Main(string[] args)
{
IUnityContainer unityContainer = new UnityContainer();
IWindsorContainer windsorContainer = new WindsorContainer();
Program unityProgram = unityContainer.Resolve<Program>();
Program castleProgram = windsorContainer.Resolve<Program>();
}
}
Run Code Online (Sandbox Code Playgroud)
UnityContainer将返回一个Program实例,其中Windsor容器将抛出ComponentNotFoundException.
我可以看到这两种行为的争论,并且不介意我最终会遇到什么,但是Prism V2 Drop 8(写作时最新的)依赖于内部的Unity行为,请求尚未注册的类.
而不是为Prism找到并注册所有这些类,我宁愿让Windsor表现得像Unity一样.我没有在谷歌找到任何帮助我这样做的东西(虽然我的术语可能是错的)和Windsor文档相当糟糕...
任何人都可以建议解决这个问题吗?
我们的应用程序不断为大量数据(比如几十到几百兆字节)分配数组,这些数据在丢弃之前会存在很短的时间.
天真地做这会导致大对象堆碎片,最终导致应用程序崩溃与OutOfMemoryException,尽管当前活动对象的大小不会过多.
我们过去成功管理过这种方法的一种方法是对阵列进行分块以确保它们不会最终出现在LOH上,其目的是通过允许内存被垃圾收集器压缩来避免碎片化.
我们的最新应用程序处理的数据比以前更多,并且在单独的AppDomain或单独进程中托管的加载项之间非常频繁地传递此序列化数据.我们采用了与以前相同的方法,确保我们的内存总是被分块并且非常小心地避免大对象堆分配.
但是我们有一个必须在外部32位进程中托管的加载项(因为我们的主应用程序是64位,加载项必须使用32位库).在特别繁重的负载下,当很多SOH内存块被快速分配并在之后不久丢弃时,即使我们的分块方法还不足以保存我们的32位加载项,并且它会因OutOfMemoryException而崩溃.
在发生OutOfMemoryException时使用WinDbg,!heapstat -inclUnrooted显示如下:
Heap Gen0 Gen1 Gen2 LOH
Heap0 24612 4166452 228499692 9757136
Free space: Percentage
Heap0 12 12 4636044 12848SOH: 1% LOH: 0%
Unrooted objects: Percentage
Heap0 72 0 5488 0SOH: 0% LOH: 0%
Run Code Online (Sandbox Code Playgroud)
!dumpheap -stat 显示这个:
-- SNIP --
79b56c28 3085 435356 System.Object[]
79b8ebd4 1 1048592 System.UInt16[]
79b9f9ac 26880 1301812 System.String
002f7a60 34 4648916 Free
79ba4944 6128 87366192 System.Byte[]
79b8ef28 17195 145981324 System.Double[]
Total 97166 objects
Fragmented blocks larger than 0.5 MB: …Run Code Online (Sandbox Code Playgroud) 在我们的应用程序中,我们有一些数据结构,其中包含一个分块的字节列表(当前公开为a List<byte[]>).我们将字节大块化,因为如果我们允许将字节数组放在大对象堆上,那么随着时间的推移,我们会遇到内存碎片.
我们也开始使用Protobuf-net来序列化这些结构,使用我们自己生成的序列化DLL.
但是我们注意到Protobuf-net在序列化时会创建非常大的内存缓冲区.浏览源代码看起来似乎它可能无法刷新其内部缓冲区,直到整个List<byte[]>结构被写入,因为它需要在缓冲区前面写入总长度.
不幸的是,这首先解决了我们的工作,首先将字节分块,最终由于内存碎片而给我们OutOfMemoryExceptions(异常发生在Protobuf-net尝试将缓冲区扩展到84k以上时,这显然是在LOH,我们的整体进程内存使用率相当低.
如果我对Protobuf-net如何工作的分析是正确的,那么有没有解决这个问题的方法呢?
更新
根据Marc的回答,这是我尝试过的:
[ProtoContract]
[ProtoInclude(1, typeof(A), DataFormat = DataFormat.Group)]
public class ABase
{
}
[ProtoContract]
public class A : ABase
{
[ProtoMember(1, DataFormat = DataFormat.Group)]
public B B
{
get;
set;
}
}
[ProtoContract]
public class B
{
[ProtoMember(1, DataFormat = DataFormat.Group)]
public List<byte[]> Data
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
然后序列化它:
var a = new A();
var b = new B();
a.B = b;
b.Data = new List<byte[]>
{
Enumerable.Range(0, 1999).Select(v => …Run Code Online (Sandbox Code Playgroud) 我有一个AngularJS服务,它执行$ http GET请求并在本地缓存响应.它旨在处理同时发生的多个调用,以便仅缓存来自最终调用的数据.
具体来说,如果发生以下情况:
结果是请求B的响应被缓存,因为它是最后启动的.
但是我在Jasmine进行单元测试时遇到了麻烦.
我可以设置两个$ httpBackend.expectGET()期望,但我只能按照它们的请求顺序刷新它们.
基本上我需要能够像这样:
$httpBackend.expectGET('/one').respond(200, data1);
$httpBackend.expectGET('/two').respond(200, data2);
myService.doSomething('/one');
myService.doSomething('/two');
$httpBackend.flush('/two');
$httpBackend.flush('/one');
expect(myService.data).toBe(data2);
Run Code Online (Sandbox Code Playgroud)
有谁能建议一个简洁的方法来实现这一目标?
我们使用System.AddIn将加载项加载到单独的子AppDomain中,如果加载项AppDomain有未处理的异常,我们会将其卸载.
因为版本2.0中.NET的默认行为是在任何AppDomain有未处理的异常时拆除整个过程,所以我们通过在App.config中使用"legacyUnhandledExceptionPolicy"选项来执行此操作,然后在未处理的情况下手动拆除该过程异常位于主AppDomain中,或者如果它位于加载项中,则卸载相应的AppDomain.
这一切都很有效,除了一个小问题:未处理的异常总是从子AppDomains冒出来到主要的,如果它们不可序列化,则无法成功跨越AppDomain边界.
相反,我们在主AppDomain中出现SerializationException,显示为UnhandledException,导致我们的应用程序自行崩溃.
我可以想到这个问题的一些可能的解决方案:
我们无法拆除未处理的SerializationExceptions(yuck)的过程.
我们可以阻止异常从子AppDomain传播到主AppDomain.
我们可以用可序列化的异常替换不可序列化的异常,可能使用序列化代理和序列化绑定.[编辑:看到为什么使用代理人无法做到这一点]
然而,第一个是非常可怕的,我一直没有成功找到如何使用跨AppDomain远程处理其他任何选项.
有人可以提供一些建议吗?任何帮助表示赞赏.
要重现,请使用以下App.config创建控制台应用程序:
<?xml version="1.0"?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true"/>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
以下代码:
class Program
{
private class NonSerializableException : Exception
{
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += MainDomain_UnhandledException;
AppDomain childAppDomain = AppDomain.CreateDomain("Child");
childAppDomain.UnhandledException += ChildAppDomain_UnhandledException;
childAppDomain.DoCallBack(
() => new Thread(delegate() { throw new NonSerializableException(); }).Start());
Console.ReadLine();
}
static void MainDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("Main AppDomain Unhandled Exception: " + e.ExceptionObject);
Console.WriteLine();
}
static void ChildAppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{ …Run Code Online (Sandbox Code Playgroud) 我的代码中有一个很大的任意JSON结构作为JObject参考。
我想序列化此结构,除非遇到JObject包含type以value 调用的属性时,"encrypted"然后要data在写入对象之前删除相邻的属性。
换句话说,如果我遇到此问题:
{
type: "encrypted",
name: "some-name",
data: "<base64-string>"
}
Run Code Online (Sandbox Code Playgroud)
它将被序列化为:
{
type: "encrypted",
name: "some-name"
}
Run Code Online (Sandbox Code Playgroud)
我无法更改结构,因此在更改之前将其克隆效率太低,因此我尝试使用JsonConverter如下方法:
public class RemoveEncryptedDataSerializer : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(JObject);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var o = (JObject)value;
if …Run Code Online (Sandbox Code Playgroud) 我正在将我们的一个项目转换为使用 Azure DevOps 而不是 AppVeyor 进行 CI。作为构建的一部分,我们使用自定义测试运行器来执行某些测试。
在 AppVeyor 中运行时,我们直接从测试运行器调用 REST API,以通知构建服务器正在运行的测试并更新其状态。这非常简单,如添加测试和更新测试文档的 REST 部分所示,并且使我们能够很好地集成到 AppVeyor 的 UI 中。
我一直在研究如何在 Azure DevOps 中做同样的事情。我找到了 REST API 的一部分,用于添加和更新测试结果。从 API 文档中尚不完全清楚这是否是我在运行管道期间使用的,或者是否适用于其他场景。我已经搜索过其他人试图做同样的事情,但到目前为止没有任何运气。大多数示例都讨论上传测试结果文件,但这似乎是发布测试结果的一种相当间接的方式,特别是因为我想在运行之前注册所有测试,然后在完成时更新其状态。
有没有人有关于在构建期间使用 Azure DevOps API 发布测试结果的任何指示或示例?
详细解决方案:
在梅林梁的回答指导下,我现在已经开始工作了。
步骤 1.首先,我创建了一个新的测试运行,这是我在构建作业(称为 )结束时Build使用 powershell 脚本执行的:
- powershell: |
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/test/runs?api-version=5.0"
$body = @{
"name" = "IntegrationTests"
"build" = @{
"id" = $env:BUILD_BUILDID
}
"isAutomated" = $TRUE
"state" = "InProgress"
}
$json = $body | …Run Code Online (Sandbox Code Playgroud) 举个简单的例子:我有一个拥有1,000,000个用户的服务,每个用户都有一些个人资料信息.我想使用actor管理此配置文件信息的CRUD操作.
在Project Orleans中,我的理解是每个用户只有一粒,所以1,000,000个虚拟粒子具有相同的actor类型(只有在使用时才会创建),每个粒子将管理存储在其中的单个用户的配置文件信息.州.随着用户的增长,谷物的数量也在增长.
在Service Fabric中,如果我正确地解释文档,它的工作方式会略有不同.我会有一个有状态的actor类型来管理所有用户的CRUD操作,为了可伸缩性,我会对actor进行分区,为每个分区负责一部分用户数据.鉴于分区选项,我看不到一种明显的方法来实现它与Project Orleans相同的细粒度方式.
我非常喜欢奥尔良项目的方法.演员只是处理单个用户的数据,可扩展性是显而易见的(更多的用户等于更多的谷物).记忆模型也很简单:一个演员按需少量状态就可以得到水分.
看起来Service Fabric的实现会稍微复杂一些.每个参与者都在处理一组用户,为了可伸缩性,我必须事先决定应该制作多少分区,因为以后无法修改.对于内存模型,每个参与者管理的数据量随着用户数量的增长而增长.
所以我的问题是:我的理解是否正确,Service Fabric中的演员比Project Orleans更粗糙?
更新
谢谢你的回答.在我的错误中,我认为一个分区包含一个actor实例,它将包含并管理分区中所有actor ID的状态.这是完全错误的.Michiel指出分区包含许多actor实例,每个actor ID一个.因此,演员可以像在奥尔良项目中那样实施.现在,这更有意义了,谢谢.
我有一个 ASP.NET 4.6 Web API 服务作为 Azure 应用服务在单个区域的单个应用服务计划中运行。我们正在修改此服务,使其部署在多个区域,并在前面有一个负载均衡器,每个区域都有自己的应用服务计划。因此,我们需要确保在每个应用服务计划上使用相同的计算机密钥,以防止用户在负载均衡器将其定向到不同的服务器时注销。
我们的应用程序已经使用 Azure 在单个应用服务计划上自动提供的机器密钥运行了一段时间。为了避免导致所有客户在过渡期间注销,我计划提取此现有计算机密钥,然后将其部署到其他区域的新应用程序服务计划上。听起来很简单,对吧?
然而提取这个密钥被证明是一个挑战。
我已经尝试过此处列出的解决方案:获取当前的 ASP.NET 计算机密钥
虽然每种方法确实返回某种密钥,但该密钥似乎与实际用于生成不记名令牌或保护刷新令牌票证的密钥不匹配。当我将这些密钥部署到其他服务器时,不记名令牌仍然被视为无效,并且尝试使用现有刷新令牌会导致响应invalid_grant。
此外,即使我在 web.config 中手动设置机器密钥(或在运行时使用此类代码),提取的机器密钥也不会与我手动设置的机器密钥匹配,这提供了进一步的证据,表明它们是什么返回的不是实际使用的机器密钥。在我的本地开发计算机和 Azure 中都是如此。
作为参考,这是我用来以三种不同方式提取解密和验证密钥的代码(删除了一些安全密码):
[DllImport(@"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll")]
internal static extern int EcbCallISAPI(IntPtr pECB, int iFunction, byte[] bufferIn, int sizeIn, byte[] bufferOut, int sizeOut);
[Route("machine-key-test")]
public async Task<JObject> GetMachineKeys()
{
return new JObject(
new JProperty("A", GetAdminData()),
new JProperty("B", GetAdminDataNoIsolateApps()),
new JProperty("C", GetAdminDataPre45()));
JObject GetAdminData()
{
string appPath = "/";
byte[] genKeys = new byte[1024];
byte[] autogenKeys = new byte[1024];
int …Run Code Online (Sandbox Code Playgroud) asp.net machinekey azure-app-service-plans azure-web-app-service
.net ×4
c# ×3
actor ×1
angularjs ×1
appdomain ×1
appveyor ×1
asp.net ×1
azure-devops ×1
chunking ×1
exception ×1
httpbackend ×1
jasmine ×1
javascript ×1
json.net ×1
machinekey ×1
orleans ×1
prism ×1
protobuf-net ×1
tfvc ×1
unit-testing ×1
windbg ×1