Web Services 在另一个线程中使用SSRS Web服务

zlhcx6iw  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(142)

我正在从www.example.com应用程序中调用SQL Server Reporting Services Web服务asp.net。我需要关闭给定报表的所有订阅。但我不希望用户必须等待所有订阅都发生,因此我希望将所有Web服务调用都放在一个单独的线程中,并立即返回给用户。
我使用的代码看起来像这样:

public static void FireAllAsync(string ReportPath)
{
    Hashtable paramValues = new Hashtable();
    ThreadPool.QueueUserWorkItem(new WaitCallback(FireAll), ReportPath);
}

public static void FireAll(object ReportPath)
{

    ReportingService rs = new ReportingService();
    rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

    Subscription[] SubList = rs.ListSubscriptions((string)ReportPath, null);

    foreach (Subscription CurSub in SubList) {
        rs.FireEvent(CurSub.EventType, CurSub.SubscriptionID);
    }

}

调用FireAll可以正常工作,但是尝试调用FireAllAsync来使用线程失败,并出现401错误。我认为问题是凭据没有正确传递。例如,下面这行代码:

rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

我对凭证缓存的工作方式没有很好的理解,所以我不明白为什么它不喜欢在单独的线程中。
我已经尝试在外部函数中获取凭据,并将它们作为参数传递,但是发生了同样的错误。
有人知道会发生什么吗?

pnwntuvh

pnwntuvh1#

当您的主线程正在执行时,它具有为其准备的模拟上下文。在经过身份验证的方案中,IIS已对用户进行身份验证,然后为该用户设置线程标记(而不是进程标记)。
因为线程令牌是为用户设置的,所以该线程然后可以代表用户(在本地机顶盒上;如果使用集成Windows身份验证(NTLM/Kerberos),则代表另一个计算机上的用户进行操作需要设置 * 委派 *)。
但是,如果您在没有任何标识信息的情况下派生一个辅助线程,则该辅助线程将在没有自己的令牌的情况下派生,因此它将使用进程令牌。
如果您可以在初始线程上执行需要执行的操作,那么就没有委托问题,只是在辅助线程上缺少用户令牌。
线程池线程将作为进程标识运行(默认情况下为NetworkService,即主机的计算机帐户,除非您的应用池设置为以SomeUser身份运行,在这种情况下,所有工作线程都将以SomeUser身份运行)-如果该用户可以访问初始用户想要的任何内容,则一切都很好。
如果没有,401镇。
有一些Web参考可以帮助解决此问题,并提供了各种可能的答案:
Link
http://aspalliance.com/articleViewer.aspx?aId=650&pId=2

相关问题