How to make synchronous RIA request

2019-08-12 17:43发布

问题:

I have an existing RIA service in which I would like to include a very simple call to find the maximum fields allowed for a certain custom object. The value will change infrequently, if ever, and I would like to call it just once when needed and then keep it on the client. However, when I need to know the value, I need to know it in a synchronous manner, as I will be using it right away.

I've tried the following, but the .Value is always just 0, since the service doesn't actually make the request when this block of code is run, but rather sometime later.

private static readonly Lazy<int> _fieldCount =
    new Lazy<int>(() =>
        {
            const int TotalWaitMilliseconds = 2000;
            const int PollIntervalMilliseconds = 500;

            // Create the  context for the RIA service and get the field count from the server.
            var svc = new TemplateContext();
            var qry = svc.GetFieldCount();

            // Wait for the query to complete. Note: With RIA, it won't.
            int fieldCount = qry.Value;
            if (!qry.IsComplete)
            {
                for (int i = 0; i < TotalWaitMilliseconds / PollIntervalMilliseconds; i++)
                {
                    System.Threading.Thread.Sleep(PollIntervalMilliseconds);
                    if (qry.IsComplete) break;
                }
            }

            // Unfortunately this assignment is absolutely worthless as there is no way I've discovered to really invoke the RIA service within this method.
            // It will only send the service request after the value has been returned, and thus *after* we actually need it.
            fieldCount = qry.Value;

            return fieldCount;
        });

Is there any way to make a synchronous, load-on-demand service call using RIA services? Or will I have to either: 1) include the constant in the client code, and push out update when/if-ever it changes; or 2) host a completely separate service, which I can call in a synchronous fashion?

回答1:

You cannot make WCF RIA work synchronously, unfortunately. What you can do is put the value in the InitParams of the <object> tag in the HTML that hosts the Silverlight. Read more: http://msdn.microsoft.com/en-us/library/cc189004(v=vs.100).aspx



回答2:

I realize the previous answer here may have been true a couple of years ago but it's not entirely true now as I have just discovered. Look at the await operator http://msdn.microsoft.com/en-us/library/hh156528.aspx

I think this exactly what you are looking for. You can call it from within an async method (must use the async modifier at the beginning of the method like: private async void dostuff()). Though the parent method is still asynchronous, it will wait for the call to the task.

Say you're doing this from a Domain Data Service. Here's an example: Note: Your DDS must return a type of IEnumerable. Before you call data from your DDS, define a private task method which retrieves the data in question like this:

private Task<IEnumerable<fieldCounts>> GetCountssAsync()
    {
        fieldCountsEnumerable_DS _context = new fieldCountsEnumerable_DS ();
        return _context.LoadAsync(_context.GetCountsQuery());
    }

You can then call that task from within your existing async ria service method or any client method really using await:

IEnumerable<fieldCounts> fieldcnts = await GetCountssAsync();
enter code here

Just know that whatever method you call this from, that method has to be async like it says in the documentation. It has to give control back to the caller.