RPC server unavailable calling OpenReadAsync - c#

I have a simple Windows Universal Platform Application that I wrote primarily to teach myself about UWP apps. It works fine, except for what appears to be a somewhat random "The RPC server is unavailable" error generated on the OpenReadAsync method on the StorageFile object.
The application simply builds a list of files to be displayed, then iterates through and displays each one on a timer. Most of the time it works fine. I can let it run for hours no problem. But every once in a while, I receive the RPC error. It seems to happen when I leave the machine for a long time so it logs me out, then I log back in and switch to my slideshow application. It doesn't happen every time, and if I try to reproduce, I can never get it to fail. It seems to be mainly when I leave the machine for a long time - like overnight.
Here is the code running when the error occurs. It happens on the OpenReadAsync method call.
StorageFile file = this._files.ElementAt(this._index++);
await this._dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
var bitmap = new BitmapImage();
var stream = await file.OpenReadAsync();
await bitmap.SetSourceAsync(stream);
this.Image = bitmap;
});
If I try to open the file using the Windows Photo viewer, even while sitting at the error, it opens fine. But even re-trying the failing line of code will not allow my app to open the file. All I can do is shut down and restart the application.
Has anyone run across anything like this? Any hints on where I should look?
Thanks.
Edit: Oh, one more thing - the files are all on a local drive. No external servers or network involved.

Related

File gets "locked" while moving operation and iis give 401 error

I have a windows service run with local system account
What my program does is :
if (File.Exists(outputPath))
{
File.Delete(outputPath);
}
File.Move(archivePath, outputPath);
Relevant folder is application folder of iis where its application pool's identity is ApplicationPoolIdentity located under c:\MyAppFolder.
My windows service does its few times a day, and my clients checks if any new version exists every 5 minutes(0,5,10,15...) and download that file.
Time to time, file is somehow get "locked" on filesystem then
iis gives 401 error
File cannot be deleted
My first question how can I repro this situation?
One patch is done by colleagues is:
var fs = File.GetAccessControl(outputPath);
fs.SetAccessRuleProtection(false, false);
File.SetAccessControl(outputPath, fs);
Although this patch, it seems error occured again,
I may apply, this solution as well.
Are those solutions are enough or necessary?
Again my first question is important "repro issue" and understand why this happens.

BackgroundDownloader on Windows 10 IoT Core does not complete on Raspberry Pi

I got that downloader code running on Windows 10 IoT Core which tries to download a file to the applications local folder if it does not exist yet. If it does, it should return the path to that file.
Spoiler: The code snippet itself is working, see below.
private async Task<string> GetAsync(string url)
{
url = WebUtility.UrlDecode(url);
string fileName = Path.GetFileName(url);
var folder = ApplicationData.Current.LocalFolder;
var destinationFile = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
if (new FileInfo(destinationFile.Path).Length > 0)
return destinationFile.Path;
var downloader = new BackgroundDownloader();
var download = downloader.CreateDownload(new Uri(url), destinationFile);
await download.StartAsync();
return destinationFile.Path;
}
Now, when the file does not exist, the code is running until line await download.StartAsync(). From there, it never returns.
In the folder, an empty file with the given name is existent but only 0kb in size - that one's created implicitly while calling CreateFileAsync() before (and that's why I check for .Length to check the file existence).
Now comes the thing:
That code is never returning, but if I kill the application (after enough time), the file gets written to disk, so the download apparantly succeeded but it did not "flush" to the file system. That does not happen if I do not kill the app, so refreshing the Windows Explorer view or looking for the file properties does not show any change in size.
I'm getting crazy on this, could somebody give me a hint? All the tips and hints from articles like those here did not work on the Pi:
BackgroundDownloader.GetCurrentDownloadsAsync returns completed downloads
Check progress of download operation which started in background task
MSDN: Background transfers: Post processing
Setup
Raspberry Pi 3
Windows 10 IoT Core 10.0.15063.0
Wired Ethernet connection
App capabilities (Package.appxmanifest)
Internet (Client & Server)
Internet (Client)
Private Networks (Client & Server)
Removable Storage
This hanging can be caused by Async and WPF context locking. Try to use Task.Wait() instead of await. WPF UI locks awaits easily.
I got my await SpiDevice.FromIdAsync(devs[0].Id, set) locked, and when I changed to devTask.Wait(), lock disappeared and device found from devTask.Result.

How to set Header when restoring Background Downloads

I'm trying to make some downloads using cookie authentication doing:
var downloader = new BackgroundDownloader();
downloader.SetRequestHeader("Cookie", "JSESSIONID=" + App.LoginGateway.JSESSIONID);
downloader.SetRequestHeader("Cookie", "JSESSIONID=" + App.LoginGateway.JSESSIONID);
Until here everything works perfectly, the problem begins when I try to restore my downloads and my JSESSIONID is expired
IReadOnlyList<DownloadOperation> downloads = null;
downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
I tried to find where could I set the request Header again but I was not capable. If I create a new BackgroundDownloader where could I set it for my download Operation?? Some Help is very appreciated
As of Windows 8.1, BackgroundTransfer does not support updating the headers associated with a DownloadOperation/UploadOperation after the operation has been created, even if the operation is Paused/Resumed. You'll need to abort the old download and create a new download with an updated JSESSIONID header.
When your application is launched, it should be using BackgroundDownloader.GetCurrentDownloadsAsync() to query for all the DownloadOperations that might have been occurring in the background while your app was suspended/terminated. Your application should then call AttachAsync on each DownloadOperation in order to attach progress and completion handlers. In this case, you should implement logic in your completion handler that can identify this particular error case and create a new download (with the new JSESSIONID) for the same content.
As an aside, if you go searching for other folks that need to post-process failed downloads like this, you may run across some people who are performing these checks in Background Tasks that they register to run on a periodic timer. While this may sound like a good idea (since it means you could retry your download without waiting for the next time the user brings your application to the foreground), keep in mind that BackgroundTransfer may hang if you attempt to call AttachAsync in a Background Task for an operation which was started in your foreground application code.

Problem with calling Console application (WCF Service) from webform

I am using a ASP.net webform application to run an existing console application which get all records from DB and send them through a third party WCF service. Locally everything is working fine. When I run the application it opens the console, gets the records and sends them. But now I pushed my files over to Test server along with the exe file and related config files. But when I access the application through the browser (test url) I get the same error message time and again and I don't see the console window. Sometimes everything works fine but never two times in a row.
The error message is:
"There was no end point listening at '.....svc' that could accept message. This is often caused by incorrect address or soap action.
System.net.webexception. Remote name could not be resolved
at System.Net.HttpWebRequest.GetRequestStream
at System.ServiceModel.Channels.HttpOutput.Webrequest.HttpOutput.GetOutputStream()
The code I have used in the webform to call console application is:
ProcessStartInfo p = new ProcessStartInfo();
p.Arguments = _updateNow.ToString();
p.FileName="something";
p.UseShellExecute = false;// tried true too without luck
Process.Start(p);
Error message denotes "there is no end point" and sounds like there is problem with the WCF service but if I double click the executable in Test there is no problem. What could be the possible problem or should I redo the console application functionality to my main webform application?
Update: After adding Thread.Sleep(3000) after Process.Start(p), I'm having no problem. So seems like main application is not waiting for the batch process to complete. How to solve this problem?
It seems like there is a short delay between starting the console application and the WCF web service becoming initialise and available to use - this is to be expected.
You could either:
Work around the issue using Thread.Sleep() and possibly with a couple of catch - retry blocks.
You could have the console application report to the creating process when it is ready to recieve requests (for example by having it write to the standard output and using redirected streams).
However at this point I'd probably reconsider the architecutre slightly - starting a new process is relativley costly, and on top of that initialising a WCF serice is also relatively costly too. If this is being done once per request then as well as the above timing issues you are also incurring performance penalties.
Is it not possible to change the architecutre slightly so that a single external process (for example a Windows service) is used for all requests instead of spawning a new process each time?

Mathematica .Net/Link in an Asp.Net application

I am using the Mathematica .Net/Link platform to create a web service to format and calculate math problems. However I am unable to get it working.
I create it using this code:
_Log.IpDebug("Starting the Kernel Link");
if (string.IsNullOrEmpty(_MathLinkArguments))
_InternelKernel = MathLinkFactory.CreateKernelLink();
else
_InternelKernel = MathLinkFactory.CreateKernelLink(_MathLinkArguments);
_Log.IpDebug("Kernel Link Started");
_InternelKernel.WaitAndDiscardAnswer();
The value of _MathLinkArguments is -linkmode launch -linkname \"C:\\Program Files\\Wolfram Research\\Mathematica\\7.0\\Math.exe\".
This piece of code is called from the Application_Start method of the global.asax.cs file.
When it gets to the WaitAndDiscardAnswer() call it gives the server error:
Error code: 11. Connected MathLink program has closed the link, but there might still be data underway.
Note: The SampleCode given with the .NET/Link package (both a console app and a WinForms app) works.
Edit:
I copied the console app sample code given with Mathematica into an asp.net page and it gave me the same error the first load and then on subsequent loads it gave me:
Error code: 1. MathLink connection was lost.
Edit2:
I forgot to mention that when I have procmon and task manager open while running my app, I can tell that Math.exe starts but it immediately exits, which makes those error code make complete sense...but doesn't explain why that happened.
To allow the .Net/Link to work in Asp.net (at least in IIS 7.5) you need to enable the property loadUserProfile on the app pool for the web site.
I am not entirely sure why this is the case, but from what I found while trying to debug this, there are some things that are gotten from the user's profile. I know for a fact that the default location of the kernel is, which explains why I couldn't use it with no arguments, and so I can only assume that other things are needed as well and without the profile it couldn't determine that.
But whatever the reason is this is required, it is, or at least it is a fix if you are getting similar problems like this in your own application.
I got the same error in a .Net WinForm application.
mathKernel = new MathKernel();
mathKernel.Compute("<< XYZ`XYZGraphs`");
The error occurred on loading the package straight after instantiating the MathKernel.
To resolve it you can wait a couple of seconds and then instantiating the MathKernel works fine. During this state where there might still be data underway the following conditions are both false:
if (!MathKernel.IsConnected)
{
MathKernel.Connect();
}
if (MathKernel.IsComputing)
{
MathKernel.Abort();
}
Edit:
I've recieved the error again and this time was able to determine the problem.
Using a command line open the MathKernel.exe and view the error message:

Categories