小编sco*_*732的帖子

在等待任务结果时会发生什么?

我正在使用HttpClient将数据发布到.NET 4.0项目中的远程服务.我不关心这个操作阻塞,所以我想我可以跳过ContinueWith或async/await并使用Result.

在调试时,我遇到了远程服务器没有响应的问题.当我逐步完成代码时,似乎我的代码在第三行停止运行...当前堆栈指针线停止突出显示为黄色,并且没有前进到下一行.它刚刚消失了.我花了一段时间才意识到我应该等待请求超时.

var client = new HttpClient();
var task = client.PostAsync("http://someservice/", someContent);
var response = task.Result;
Run Code Online (Sandbox Code Playgroud)

我的理解是调用任务上的Result导致代码同步执行,表现得更像这样(我知道HttpClient中没有Post方法):

var client = new HttpClient();
var response = client.Post("http://someservice/", someContent);
Run Code Online (Sandbox Code Playgroud)

我不确定这是件坏事,我只是试图理解它.真的是因为HttpClient正在返回Tasks而不是直接返回结果,我的应用程序即使在我认为我正在避免它时也会自动利用异步吗?

c# asynchronous task

36
推荐指数
1
解决办法
3万
查看次数

涉及属性中类型的库中DI的最佳实践

我正在开发一个简化应用程序配置的库.本质上,库的使用者要么使用属性装饰他们的配置类,要么在代码中以声明方式初始化设置.可以指定一个或多个源,从中读取/写入配置属性(Accessors)或从类继承默认值.例如,以下内容:

[ConfigurationNamespace(DefaultAccessors = new Type[] { typeof(AppSettingsAccessor) })]
public class ClientConfiguration : Configuration<IClientConfiguration>
{
    [ConfigurationItem(Accessors = new Type[] { 
        typeof((RegistryAccessor)) 
     })]
    public bool BypassCertificateVerification { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

相当于

var config = new Configuration<IClientConfiguration>();
config.SetDefaultAccessors(new[] { typeof(AppSettingsAccessor) });
config.SetPropertyAccessors(
    property: x => x.BypassCertificateVerification,
    accessors: new[] { typeof(RegistryAccessor) }
);
Run Code Online (Sandbox Code Playgroud)

Accessors处理来自各种来源(AppSettings,注册表,.ini等等)的读写.我想让消费者扩展功能以满足他们的需求.我想保持IoC容器不可知.Type []约束是给我的,因为由于编译时与运行时问题,我无法在属性中指定类型.

有没有办法有一个默认机制来实例化这些(例如,基于Activator.CreateInstance的东西),但也允许消费代码在运行时实例化这些访问器而不使用服务定位器/依赖关系解析器模式?我一直在阅读很多关于为什么服务定位器/依赖解析器模式是一个邪恶的反模式,但我无法找到一个更好的工具.我看到MVC框架和SignalR库使用依赖解析器.他们100%的时间是邪恶还是这是一个边缘案件?据我所知,抽象工厂模式不会削减它,因为它不喜欢Type参数.

在这种特殊情况下,基于属性的配置比声明方法更有用,所以我不想放弃我的配置属性(这将允许我将Type更改为IConfigurationAccessor并切换到工厂方法).

c# dependency-injection inversion-of-control

5
推荐指数
1
解决办法
191
查看次数

我应该等待使用TaskCompletionSource的同步Task <T>吗?

我正在尝试编写一些包含非基于任务的库(MSDeploy API)的库代码.基本上,我从远程服务器获取东西并进行分析.我正在使用TaskCompletionSource包装同步MSDeploy API b/c虽然它不是基于任务的,但我可以获得CancellationToken支持来使用该库的CancelCallback委托."获取东西"代码作为同步API公开,但它受I/O限制.分析代码是I/O和CPU密集型的,并且已经基于任务.它不会产生任何任务/线程(我将在调用代码中执行此操作).

我最近一直在阅读很多关于这些东西的博客,但我仍然试图了解async/await/ConfigureAwait()并找出编写和调用复合方法(GetAndAnalyzeStuff)的最佳方法.几个问题:

  1. 是否在GetAndAnalyzeStuff方法中等待基于TaskCompletionSource的调用和TPL异步调用,或者只是异步调用(我应该在调用GetStuff时使用.Wait()).
  2. 你能告诉我在某处是否需要ConfigureAwait(false)吗?如果是这样,你怎么知道?
  3. 如何在调用代码(下面的Main())中处理Task.Run()调用?我更喜欢这个在后台运行,我认为在库/ API代码中启动任务是不好的做法.我假设Task.Run比Task.Factory.StartNew b/c更合适我正在做异步的东西.

下面的代码(使用.NET 4.5.1):

public Task<Stuff> GetStuff(CancellationToken token) 
{
    var tcs = new TaskCompletionSource<Stuff>(tcs);
    try 
    {
        var stuff = new Stuff();
        using (var stuffGetter = new StuffGetter()) 
        {
            stuffGetter.CancelCallback = () => cancellationToken.IsCancellationRequested;

            for (var x = 0; x < 10; x++) 
            {
                if (token.IsCancellationRequested) 
                {
                    tcs.SetCancelled();
                    return tcs.Task;
                }

                // StuffGetter's doing IO & would ideally have an API w/Task<Stuff>, but
                // it doesn't and it's not my code.
                var thing …
Run Code Online (Sandbox Code Playgroud)

.net c# asynchronous async-await

1
推荐指数
1
解决办法
1980
查看次数