小编Luk*_*s K的帖子

正确使用Task.Run时和async-await时

我想问你关于正确架构何时使用的意见Task.Run.我在WPF .NET 4.5应用程序(使用Caliburn Micro框架)中遇到了滞后的UI.

基本上我在做(非常简化的代码片段):

public class PageViewModel : IHandle<SomeMessage>
{
   ...

   public async void Handle(SomeMessage message)
   {
      ShowLoadingAnimation();

      // Makes UI very laggy, but still not dead
      await this.contentLoader.LoadContentAsync();

      HideLoadingAnimation();
   }
}

public class ContentLoader
{
    public async Task LoadContentAsync()
    {
        await DoCpuBoundWorkAsync();
        await DoIoBoundWorkAsync();
        await DoCpuBoundWorkAsync();

        // I am not really sure what all I can consider as CPU bound as slowing down the UI
        await DoSomeOtherWorkAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

从我阅读/看到的文章/视频中,我知道await async不一定在后台线程上运行,并且需要在后台开始工作,需要等待它Task.Run(async () => …

c# asynchronous task async-await

288
推荐指数
2
解决办法
25万
查看次数

在WebApi中使用HttpContext.Current是危险的,因为异步

我的问题与此有点相关:具有依赖注入的HttpContext.Items的WebApi等价物.

我们想使用Ninject在WebApi区域中使用HttpContext.Current注入一个类.

我担心的是,这可能非常危险,因为在WebApi(一切?)是异步的.

如果我在这些方面有误,请纠正我,这是我到目前为止调查的内容:

  1. HttpContext.Current通过Thread获取当前上下文(我直接查看了实现).

  2. 在异步任务中使用HttpContext.Current是不可能的,因为它可以在另一个Thread上运行.

  3. WebApi使用IHttpController和method Task<HttpResponseMessage> ExecuteAsync=>每个请求都是async =>你不能在action方法中使用HttpContext.Current.它甚至可能发生,更多的请求是通过相同的线程在同一个线程上执行的.

  4. 为了创建带有注入内容的控制器到构造函数中,IHttpControllerActivator与sync方法一起使用IHttpController Create.这是,ninject创建Controller及其所有依赖项.


  • 如果我在所有这4点中都是正确的,那么在动作方法或下面的任何层中使用HttpContext.Current是非常危险的,并且可能会产生意外结果.我看到很多公认的答案正是如此.恕我直言,这可以工作一段时间,但会在负载下失败.

  • 但是当使用DI创建一个Controller及其依赖项时,它是好的,因为它运行在一个独立的线程上.我可以从构造函数中的HttpContext获取一个值,它会安全吗?.我想知道每个Controller是否在每个请求的单个线程上创建,因为这可能会导致重负载下的问题,其中可以使用来自IIS的所有线程.

只是为了解释为什么我要注入HttpContext的东西:

  • 一种解决方案是在控制器动作方法中获取请求,并将所有层的所需值作为参数传递,直到它在代码深处使用.
  • 我们想要的解决方案:它们之间的所有层都没有被这个感染,我们可以在代码深处使用注入的请求(例如在一些依赖于URL的ConfigurationProvider中)

    如果我完全错误或者我的建议是正确的,请告诉我你的意见,因为这个主题似乎非常复杂.Thx提前!

multithreading asynchronous ninject httpcontext asp.net-web-api

61
推荐指数
2
解决办法
4万
查看次数

在MVC5中的Owin Identity中重新生成reinrateIdentityCallback中的Claim

我正在使用带有Owin身份的MVC5.

我正在努力在regenerateIdentityCallback中重用任何自定义声明.

我在Startup中有这个配置(在新MVC项目的标准模板中提供)

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, Guid>(
                    validateInterval: TimeSpan.FromSeconds(10),
                    regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                    getUserIdCallback: (user) => Guid.Parse(user.GetUserId()))
            }
        });
Run Code Online (Sandbox Code Playgroud)

GenerateUserIdentityAsync看起来像这样:(以及模板中的标准)

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, Guid> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

        // I want here instead of generating new one, just reuse the previous one
        userIdentity.AddClaim(new Claim(ClaimTypes.Sid, Guid.NewGuid().ToString()));

        return userIdentity;
    }
Run Code Online (Sandbox Code Playgroud)

问题是,我无法重复索赔,而且我总是必须为它获得新的价值.在我看到Identity dll的调查之后this,该用户的实例没有声明,因为它是来自数据库的新用户,并且userIdentity只有标准声明为Id和UserName,它们是由CreateIdentityAsync方法创建的.从HttpContext.Current获取用户是不可能的,在这个地方它是null.

重用Claim以保留Cookie中的某些值的最佳方法是什么?我可能误解了索赔的目的.请事先提供帮助

asp.net-mvc claims owin asp.net-identity

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

使用带有命令行参数的 MSBuild 部署数据库项目失败

我无法通过 msbuild 使用命令行参数部署数据库项目。我想要:

  • 使用发布 xml 配置文件
  • 将连接字符串定义为命令行参数

但这似乎无缘无故地不可能。肯定有一些我遗漏的简单问题。我尝试了以下变体:

msbuild /t:SqlDeploy /p:SqlPublishProfilePath="test.publish.xml" /p:TargetConnectionString="Data Source=..." Database.sqlproj

  • 部署数据库
  • test.pubhlish.xml 中的值被忽略

msbuild /t:Build /t:Deploy /p:SqlPublishProfilePath="test.publish.xml" /p:TargetConnectionString="Data Source=..." Database.sqlproj

  • 部署数据库
  • test.pubhlish.xml 中的值被忽略

msbuild /t:Build /t:Publish /p:SqlPublishProfilePath="test.publish.xml" /p:TargetConnectionString="Data Source=..." Database.sqlproj

  • 失败并出现错误:Deploy Error : The connection string is not valid
  • 使用 test.publish.xml 文件中的值(当 test.publish.xml 包含 TargetConnectionString 时,数据库部署正确)

在所有 3 种情况下,我都使用完全相同的 ConnectionString,因此它不是连接字符串中的拼写错误或错误。我需要使用第三个变体,但这只是失败了..我错过了什么?

deployment msbuild publish database-project sql-server-data-tools

7
推荐指数
0
解决办法
1696
查看次数

为什么即使在WPF应用程序生命周期中处理程序是async void,Application.Exit事件仍然有效?

我有一个问题如何等待WPF生命周期方法中的异步方法(使用Caliburn-Micro框架)(例如OnActivate,OnInitialized,OnExit - 它直接绑定到Application.Exit事件)

这篇文章准确地描述了我的问题:http://mark.mymonster.nl/2013/07/10/donrsquot-make-your-application-lifetime-events-async-void(现在我正在考虑使用本文中的解决方案) ,但第一眼看起来有点矫枉过正)

我需要在OnExit hanlder中等待一些异步方法,所以我把它作为异步.它有效.的种类.我不明白为什么?,但在调用Application.Exit事件时,它会以某种方式等待,直到该方法完成,即使处理程序是异步void.你能解释一下这有可能吗?这样安全吗?还是只是自信?Async void应仅用于顶级事件,是这种情况吗?

我查看了System的代码.绑定看起来像这样:

public event EventHandler Exit
{
  add
  {
    XcpImports.CheckThread();
    this.AddEventListener(DependencyProperty.RegisterCoreProperty(20053U, (Type) null), (Delegate) value);
  }
  remove
  {
    XcpImports.CheckThread();
    this.RemoveEventListener(DependencyProperty.RegisterCoreProperty(20053U, (Type) null), (Delegate) value);
  }
}
Run Code Online (Sandbox Code Playgroud)

这真是神秘,我无法通过调用此事件来了解.net框架中真正发生的事情.

同样奇怪的是,当我不使用ConfigureAwait(false)时,在处理程序中调用等待Task.Delay(1)会导致DeadLock .所以我想说有一些地方.Wait()深入使用.net代码.

注意:当我按照预期生成OnActivate,OnInitialized处理程序async时,页面不会等到处理程序完成.

谢谢你的回答!

.net c# wpf asynchronous application-lifecycle

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

在 Application Insights 中将变量与数组一起使用

我想使用一个包含数组的变量,所以我可以将它与in过滤器一起使用。

这有效:

traces
| where cloud_RoleName in ("A", "B")
Run Code Online (Sandbox Code Playgroud)

这不起作用(语法错误):

let cloudRoleNames = ("A", "B");
traces
| where cloud_RoleName in cloudRoleNames
Run Code Online (Sandbox Code Playgroud)

我想使用数组作为变量,以便能够一次在更多连接中使用相同的过滤器。作为一种解决方法,我使用第一个工作变体,但它并不理想。我尝试了各种方法 - 以及通过解析 json 但没有任何效果。我错过了一些明显的东西吗?谢谢

azure-application-insights azure-data-explorer

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