我试图用一种新的语法替换我的旧的"即发即忘"调用,希望更简单,它似乎在逃避我.这是一个例子
class Program
{
static void DoIt(string entry)
{
Console.WriteLine("Message: " + entry);
}
static async void DoIt2(string entry)
{
await Task.Yield();
Console.WriteLine("Message2: " + entry);
}
static void Main(string[] args)
{
// old way
Action<string> async = DoIt;
async.BeginInvoke("Test", ar => { async.EndInvoke(ar); ar.AsyncWaitHandle.Close(); }, null);
Console.WriteLine("old-way main thread invoker finished");
// new way
DoIt2("Test2");
Console.WriteLine("new-way main thread invoker finished");
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
两种方法都做同样的事情,但是我似乎已经获得了(没有必要EndInvoke和关闭处理,这仍然有点争议)我正在以新的方式失去等待a Task.Yield(),这实际上带来了一个新的问题必须重写所有现有的异步F&F方法只是为了添加一个单行.在性能/清理方面是否有一些无形的收获?
如果我无法修改背景方法,我将如何应用异步?在我看来,没有直接的方法,我将不得不创建一个等待Task.Run()的包装器异步方法?
编辑:我现在看到我可能会错过一个真正的问题.问题是:给定一个同步方法A(),如何使用async/ await以一种即发即忘的方式异步调用它,而不会得到比"旧方式"更复杂的解决方案
linq中.edmx和.dbml文件有什么区别?在VS 2008中哪个数据源是edmx或dbml的最佳选择?在VS 2008中使用edmx文件会出现任何问题?我可以在VS-2008中使用edmx吗?
将 VS 连接服务 (NSwag) 注入类/控制器的首选方法是什么?我在网上找到了很多使用这种形式的建议:
services.AddHttpClient<IClient, Client>((provider, client) =>
{
client.BaseAddress = new System.Uri("https://some.baseurl/");
});
Run Code Online (Sandbox Code Playgroud)
但这会导致错误
{"errorMessage":"Unable to resolve service for type 'System.String' while attempting to activate 'xxx.Client'."}
Run Code Online (Sandbox Code Playgroud)
这来自 中自动生成的客户端类obj,它似乎在构造函数中强制使用字符串 BaseUrl,这当然 DI 无法解析:
public Client(string baseUrl, System.Net.Http.HttpClient httpClient)
{
BaseUrl = baseUrl;
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
Run Code Online (Sandbox Code Playgroud)
此基本 URL 随后会被强制写入 url 构建器代码中,因此无法真正绕过它。然而,即使网上使用部分扩展客户端类的解决方案似乎也完全忽略了 auto-gen 类中的 baseUrl (就像这里)。就好像它不存在一样(这很奇怪,NSwag 之前生成了不同的构造函数吗?)。该类是通过 csproj 生成的:
<ItemGroup>
<OpenApiReference Include="OpenAPIs\swagger.json" CodeGenerator="NSwagCSharp" Namespace="xxx" ClassName="Client">
<SourceUri>https://localhost:44353/swagger/v1/swagger.json</SourceUri>
</OpenApiReference>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
这会导致目标构建调用:
2>GenerateNSwagCSharp:
2> "C:\.<path>./tools/Win/NSwag.exe" openapi2csclient …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用内置DI机制获得符合ASP.NET Core 2.1应用程序的.NET Framework类库.现在,我创建了一个配置类,并在appsettings.json中添加了相应的部分:
services.Configure<MyConfig>(Configuration.GetSection("MyConfiguration"));
services.AddScoped<MyService>();
Run Code Online (Sandbox Code Playgroud)
在类lib中:
public class MyService
{
private readonly MyConfig _config;
public MyService(IOptions<MyConfig> config)
{
_config = config.Value;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,为了构建这个classlib,我必须添加Microsoft.Extensions.OptionsNuGet包.问题是,程序包带有很多依赖项,看起来相当过分,只是为了一个接口而添加.
因此,最终的问题是,"我可以采用另一种方法来配置位于.NET Framework类库中的DI服务吗?
dependency-injection asp.net-core .net-4.7.1 asp.net-core-2.1
我正在使用IIS7.5强制我的Web应用程序自动加载(startMode="AlwaysRunning"),我现在想要预加载我的缓存数据.我有点困惑,因为两种方法看起来相同:
Application_Start在global.asax中使用serviceAutoStartProviders在IIS中配置文件它们似乎相当多余并且做同样的事情.如果它们是,我想我宁愿使用而Application_Start不是在IIS配置文件中创建代码依赖项.有什么建议?
我已经读过这个主题:C#Thread safe fast(est)计数器,并在我的并行代码中实现了这个功能.据我所知,它一切正常,但它的处理时间明显增加,大约10%左右.
它一直困扰着我,我认为问题在于我在小数据片段上做了大量相对便宜(<1量子)的任务,这些片段很好地分配并可能充分利用缓存局部性,从而以最佳方式运行.根据我对MESI的了解,我最好的猜测是,x86 LOCK前缀Interlocked.Increment将高速缓存行推入独占模式,并强制其他内核上的高速缓存未命中,并强制高速缓存重新加载每个并行传递,只是为了增加此计数器.有100ns-ish延迟缓存未命中和我的工作量似乎加起来.(然后,我可能是错的)
现在,我没有看到解决方法,但也许我错过了一些明显的东西.我甚至考虑使用n个计数器(对应于并行化程度),然后在特定核心上递增每个,但是它似乎不可行(检测我所使用的核心可能会更昂贵,更不用说详细的if/then/else结构和搞乱执行管道).关于如何打破这头野兽的任何想法?:)
假设我有一个List<IEnumerable<double>>包含可变数量的无限双数源.让我们说它们都是波发生器功能,我需要将它们叠加到单个波形发生器中,IEnumerable<double>简单地通过从每个波形中取出下一个数字并将它们相加.
我知道我可以通过迭代器方法做到这一点,如下所示:
public IEnumerable<double> Generator(List<IEnumerable<double>> wfuncs)
{
var funcs = from wfunc in wfuncs
select wfunc.GetEnumerator();
while(true)
{
yield return funcs.Sum(s => s.Current);
foreach (var i in funcs) i.MoveNext();
}
}
Run Code Online (Sandbox Code Playgroud)
然而,它似乎相当"行人".是否有LINQ-ish方法来实现这一目标?
我需要一种方法将<samlp:response>消息发布到某个URL,它相当简单,.NET帮助我使用Saml2Assertion类,但我似乎无法找到一种方法将该断言包装在响应中并将其序列化(甚至无需手动发送)后)?
Saml2Assertion assert = new Saml2Assertion(new Saml2NameIdentifier("SAMLIssuer"));
assert.Subject = new Saml2Subject(new Saml2NameIdentifier("10001", new Uri("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent")));
Saml2AuthenticationContext context = new Saml2AuthenticationContext(new Uri("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"));
assert.Statements.Add(new Saml2AuthenticationStatement(context, DateTime.Now));
string assertion;
using (var sw = new StringWriter())
{
var xws = new XmlWriterSettings();
using (var xw = XmlWriter.Create(sw, xws))
{
var handler = new Saml2SecurityTokenHandler();
handler.WriteToken(xw, new Saml2SecurityToken(assert));
}
assertion = sw.ToString();
}
Run Code Online (Sandbox Code Playgroud)
我得到的断言的XML似乎很好:
<?xml version="1.0" encoding="utf-16"?>
<Assertion ID="_fc348927-c0bf-4955-b98f-483043d8dedd" IssueInstant="2017-04-19T11:29:38.464Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>SAMLIssuer</Issuer>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">10001</NameID>
</Subject>
<AuthnStatement AuthnInstant="2017-04-19T11:29:39.040Z">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
</AuthnContext> …Run Code Online (Sandbox Code Playgroud) 我有一个非Wcf服务器,我从WCF客户端调用,我需要访问已注册的soap故障,如果服务器抛出它(它包含我需要用户的反馈).我使用了如何从WCF客户端访问SOAP 1.1故障详细信息中的示例(没有错误契约),但是给定了一个痛苦我已经在wsdl中定义了故障契约,至少每个SOAP规范,并且错误包含错误代码和错误字符串.
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="http://www.cisco.com/BTS10200/i01" xmlns="http://www.w3.org/2001/XMLSchema">
...
<complexType name="BtsSoapException">
<sequence>
<element name="error_code" type="xsd:int"/>
<element name="error_string" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
<element name="fault" type="impl:BtsSoapException"/>
...
<wsdl:message name="BtsSoapException">
<wsdl:part element="impl:fault" name="fault"/>
</wsdl:message>
...
<wsdl:portType name="Bts10200Operations">
<wsdl:operation name="login">
<wsdl:input message="impl:loginRequest" name="loginRequest"/>
<wsdl:output message="impl:loginResponse" name="loginResponse"/>
<wsdl:fault message="impl:BtsSoapException" name="BtsSoapException"/>
</wsdl:operation>
...
Run Code Online (Sandbox Code Playgroud)
服务导入可以正确识别所有这些并生成正确的代码构造:
[System.Runtime.Serialization.DataContractAttribute(Name="BtsSoapException", Namespace="http://www.cisco.com/BTS10200/i01")]
[System.SerializableAttribute()]
public partial class BtsSoapException : object ...
....
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.cisco.com/BTS10200/i01", ConfigurationName="CiscoBTSService.Bts10200Operations")]
public interface Bts10200Operations {
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
[System.ServiceModel.FaultContractAttribute(typeof(TestCiscoBTS.CiscoBTSService.BtsSoapException), Action="", Name="fault")]
TestCiscoBTS.CiscoBTSService.loginResponse login(TestCiscoBTS.CiscoBTSService.loginRequest request);
...
Run Code Online (Sandbox Code Playgroud)
当我login()使用无效帐户调用时,我会根据wsdl获得正确的响应: …
我有一个关于await/async的问题,并且在与预期稍有不同的场景中使用异步方法,例如没有直接等待它们.例如,让我们说我需要并行完成两个例程,其中两个都是异步方法(它们在内部等待).我正在使用await TAsk.WhenAll(...)它反过来期望某种任务列表等待.我做的是这样的:
await Task.WhenAll(new Task[]
{
Task.Run(async () => await internalLoadAllEmailTargets()),
Task.Run(async () => await internalEnumerateInvoices())
});
Run Code Online (Sandbox Code Playgroud)
这似乎对我来说过于复杂,因为我正在创建异步任务,其唯一目的是调用另一个任务.我不能只使用从异步方法状态引擎返回的任务吗?然而,我没有这样做,因为编译器将每个直接提到的异步方法都视为一个调用点:
// this doesn't seem to work ok
await Task.WhenAll(new Task[]
{
internalLoadAllEmailTargets(),
internalEnumerateInvoices()
});
Run Code Online (Sandbox Code Playgroud)
如果像这样,它似乎一个接一个地同步调用,如果我等待在方法前面,它就不再是一个任务.是否有关于如何在普通等待之外处理异步方法的规则书?
c# ×8
asynchronous ×2
linq ×2
.net ×1
.net-4.5 ×1
.net-4.7.1 ×1
asp.net ×1
asp.net-core ×1
async-await ×1
c#-5.0 ×1
cpu-cache ×1
iis ×1
iis-7.5 ×1
interlocked ×1
linq-to-sql ×1
mesi ×1
nswag ×1
saml-2.0 ×1
soap ×1
swagger ×1
wcf ×1
wcf-client ×1
wif ×1