views:

833

answers:

2

I'm getting the error:

"This report requires a default or user-defined value for the report parameter '*'. To run or subscribe to this report, you must provide a parameter value."

very occasionally from my reporting server even when the value '*' is being populated. Any ideas or leads that might allow me to track it down. Some points.

  • I run the reports 4-way asynchronously (meaning 4 threads generating reports at a time).
  • The reports have 2 provided parameters (always supplied) and one derived parameter.
  • I run 1,000 reports per session with ~250 reports per thread.
  • Sometimes the error will hit after a few seconds, sometimes after many hours.

    using System;
    using System.Globalization;
    using System.IO;
    using Cns.ReportExecution2005;
    
    
    public class PdfGenerator
    {
        private readonly ReportExecutionService reportExecutionService;
        public PdfGenerator(string executionServiceAddress)
        {
            // Create a new proxy to the web service
            this.reportExecutionService = new ReportExecutionService
                                              {
                                                  Credentials = System.Net.CredentialCache.DefaultNetworkCredentials,
                                                  Url = executionServiceAddress
                                              };
        }
        public Stream GenerateReport(string reportName, string format, ReportGeneratorParameter[] parameters)
        {
            if (reportName == null)
            {
                throw new ArgumentNullException("reportName");
            }
            if (format == null)
            {
                throw new ArgumentNullException("format");
            }
            this.reportExecutionService.LoadReport(reportName, null);
            if (parameters != null)
            {
                var executionParameters = new ParameterValue[parameters.Length];
                for (int i = 0; i < parameters.Length; ++i)
                {
                    executionParameters[i] = new ParameterValue
                    {
                        Label = parameters[i].Name,
                        Name = parameters[i].Name,
                        Value = Convert.ToString(parameters[i].Value, CultureInfo.InvariantCulture)
                    };
                }
                this.reportExecutionService.SetExecutionParameters(executionParameters, "en-us");
            }
            string extension;
            string encoding;
            string mimeType;
            Warning[] warnings;
            string[] streamIDs;
            byte[] results = this.reportExecutionService.Render(format, null, out extension, out encoding, out mimeType, out warnings, out streamIDs);
            return new MemoryStream(results);
        }
    }
    
A: 

How is the report code being executed, is it a series of SELECT statements or stored procedures? If you haven't already, you might consider modularizing each report into its own stored proc to make it somewhat easier to manage, and also to isolate its scope.

Darth Continent
This isn't so much an answer as a question (really should be a comment to my question). But to answer your question, it's a series of select statements due to security constraints.
Orion Adrian
Ahh sorry, I'll be more mindful of the comment vs answer in future.
Darth Continent
+1  A: 

When working with external web services it's important to realize that each request made through an instance of automatically generated wrapper class is tied to all other calls made through that instance. So here one PdfGenerator class is being instantiated, but the four threads that are making calls to it are making them all through the same interface so that you have:

Thread A: Setup Parameters Thread B: Setup Parameters Thread A: Execute (consuming thread B's parameters) Thread B: Execute (no parameters given, exception thrown)

Each thread will need its own instance of the PdfGenerator class in that each one needs its own instance of the ReportExecutionService

Orion Adrian
Glad you figured this out.
matt eisenberg