【问题标题】:Threading Task not executing in IIS线程任务未在 IIS 中执行
【发布时间】:2014-09-23 07:31:58
【问题描述】:

我有一个使用表单身份验证模式的 .Net 应用程序,并且有一个调用异步任务的函数。下面是任务的sn-p:

Task.Factory.StartNew(() => { UploadFunction(); }, tokenSource.Token, TaskCreationOptions.LongRunning,TaskScheduler.Default);

当我在 Visual Studio IDE 上进行测试时,线程工作正常。问题是当我部署它时,线程任务似乎被系统跳过或不执行。

我读过一篇文章,这可能是由 IIS 中的权限引起的:

http://codemine.net/post/Thread-Not-working-in-Aspnet-When-deployed-to-IIS

调整上述文章中的解决方案以在表单身份验证中实现,下面是代码:

[System.Runtime.InteropServices.DllImport("advapi32.dll", EntryPoint = "LogonUser")]
private static extern bool LogonUser(
         string lpszUsername,
         string lpszDomain,
         string lpszPassword,
         int dwLogonType,
         int dwLogonProvider,
         ref IntPtr phToken);

    public JsonResult uploadimages(){

         try{

            IntPtr token = new IntPtr(0);
                        token = IntPtr.Zero;

                        bool returnValue = LogonUser("Administrator", "WIN-82CH4949B3Q", "Neuron14",
                                         3,
                                         0,
                                         ref token);

            WindowsIdentity newId = new WindowsIdentity(token);
            WindowsImpersonationContext impersonatedUser = newId.Impersonate();

            var task2 =     Task.Factory.StartNew(() => { UploadFunction(); }, tokenSource.Token, TaskCreationOptions.LongRunning,TaskScheduler.Default);

            impersonatedUser.Undo();

            return Json(new { message = "Success" }, "text/plain; charset=utf-8");

         }

         catch (ex Exception)
         {
            return Json(new { error= ex.Message }, "text/plain; charset=utf-8");
         }
    }

将上述代码实现到系统中,一旦部署在 IIS 中,仍然不会执行线程。我真的很难解决这个问题,因为我真的不知道为什么线程在部署时没有执行。

【问题讨论】:

  • 为什么不能呢?将所有必要的数据传递给函数。此外,任务不会“跳过”。确保您收到所有错误的通知。即发即弃在生产中不可行,因为错误会丢失。
  • 那么上面的实现是一劳永逸的吗?所有必要的数据都通过了。我不太确定错误捕获。如何确保代码将所有错误通知系统?
  • 在我的书中不观察任务的结果是火灾和遗忘。确保 UploadFunction 具有 try-catch-all 并针对每个错误向您发送一封邮件。您链接到的帖子是关于在请求线程上提取数据并将其传递到工作线程/任务。那篇文章对你的情况有什么意义?似乎您可以使用相同的方法。
  • 文章提出的问题,其中他的代码是线程在部署时无法正常工作,这与我的问题相同。文章直接使用了System.Security.Principal.WindowsIdentity。我无法使用它,因为我使用的是表单身份验证模式。
  • 那你为什么不使用相当于Forms Authentication Mode的方式呢?似乎是 FormsIdentity 或 IIdentity。

标签: c# asp.net-mvc multithreading iis task


【解决方案1】:

当您尝试冒充 Windows 身份时出现问题:

WindowsIdentity newId = new WindowsIdentity(token);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();

var task2 =     Task.Factory.StartNew(() => { UploadFunction(); }, tokenSource.Token, TaskCreationOptions.LongRunning,TaskScheduler.Default);

impersonatedUser.Undo();

问题在于Impersonate 函数仅适用于该线程,而您的UploadFunction 正在另一个线程上运行。

这是对您的代码的修改,它在后台任务的线程上调用了 Impersonate 方法:

WindowsIdentity newId = new WindowsIdentity(token);
var task2 = Task.Factory.StartNew(() => 
                                 {
                                     using(WindowsImpersonationContext wi = newId.Impersonate())
                                     {
                                          UploadFunction();
                                     }
                                 },
                                 tokenSource.Token,
                                 TaskCreationOptions.LongRunning,
                                 TaskScheduler.Default
                               );

我的猜测是它可以在您的本地计算机上运行,​​因为您正在上传到允许匿名访问的文件夹。您的生产服务器上的权限会更加严格。

【讨论】:

  • 您好 Andrew,我尝试了您的代码,但仍然无法在 IIS 上运行。关于如何在服务器中配置匿名访问的任何想法?谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多