invalid cross-thread access in release - silverlight

I have a lightswitch application needs to generate Crystal Report from it's WCF Ria. In the development runtime I am able to generate correctly without errors, but when I push it to release environment it prompt error - invalid cross-thread access.
I've read some articles already and it is very likely Silverlight UI Thread problem
partial void GenerateReport_Execute()
{
try
{
GenerateCrystalReport.Load();
var temp = DataWorkspace.QUMCrystalReportDomainData.GenerateCrystalReport(SearchQuery.SelectedItem.GroupId, sQuarter, sYear, eQuarter, eYear);
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
var uri = new Uri("C:\\Temp\\ReportTest.pdf", UriKind.RelativeOrAbsolute);
if (AutomationFactory.IsAvailable)
{
var shell = AutomationFactory.CreateObject("Shell.Application");
shell.ShellExecute(uri.ToString());
}
else if (!System.Windows.Application.Current.IsRunningOutOfBrowser)
{
HtmlPage.Window.Navigate(uri, "_blank");
}
else
{
throw new InvalidOperationException();
}
});
}
catch ( Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Am I doing incorrectly? please help me identify this.
Thanks in Advance
Sam

Answering my question, basically that messagebox at bottom is causing the UI problem.
Lightswitch's dispatcher is not same as wpf's dispatcher(what that messagebox uses), please correct if I'm wrong

Related

WPF MVVM WebBrowser dispose

I am having WebBrowser in my WPF application. I use it for viewing pdf files. But after 50 files are viewed the app throws an exception. So we decided to dispose webbrowser before opening next pdf.
The thing is I do not know how exactly to do that. When I dispose webbrowser it is unbinded and no pdf is viewed anymore. It makes sence, but how to do that correctly?
Here is my code:
public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
WebBrowser browser = o as WebBrowser;
if (browser != null)
{
try
{
browser.Dispose();
browser = null;
browser = new WebBrowser();
}
catch
{
}
string uri = e.NewValue as string;
try
{
if (uri != null)
{
browser.Navigate(new Uri(uri, UriKind.Absolute));
}
}
catch (Exception exception)
{
ExceptionPolicy.HandleException(exception, ExceptionPolicies.General);
}
}
}
And xaml part:
<WebBrowser Grid.Row="0" Behaviour:WebBrowserBehaviour.BindableSource="{Binding WebBrowserData}"
LoadCompleted="WebBrowser_LoadCompleted" />
Basically the problem sounds like you have a memory leak. To help identify it you should use software designed that that purpose. RedAnt has a nice library that I believe has a free trial you can use to help determine what the exact cause of the issue is.
To dispose after loading you can do what is suggested here:
How to dispose of a web browser control after show
But I would suggest you prove that is the problem first by watching the memory or using a tool designed to help detect leaks.

CRM 2011 - Silverlight App that execute synchronous plug-in

Hi Im new at Silverlight/async programming
Situation: Silverlight app as a webresource that make CRUD operations
Problem: The entity have a plugin step registered to it as Synchronous. Then in silverlight when the code execute the EndSaveChages(results) method I get a SystemException.
The message received is:
The current object did not originate the async result.Parameter name:
asyncResult
I tried using a lock, Thread.Sleep, While and the Dispatcher but nothing help. There is a way to hold the process until I receive the asycResult?
Code:
private void OnUpdateRecordComplete (IAsyncResult result)
{
try
{
while (!result.IsCompleted)
{
}
Thread.Sleep(1000);
xrmsm_scores updatedRecord = result.AsyncState as xrmsm_scores;
context.EndSaveChanges(result);
// MessageBox.Show("Save Completed!");
MessageBox.Show(updatedRecord.xrmsm_studentsName.Trim() + "'s Grade has been updated!");
//MessageBox.Show("HUGE SUCCESS!");
}
catch (DataServiceRequestException se)
{
MessageBox.Show("The score information could not be saved.\nReason: " + getXMLError(se), "Error!", MessageBoxButton.OK);
studentName = string.Empty;
}
catch (SystemException se)
{
isSaved = true;
//string error = se.Message.Replace('"', '\'').Replace("\r\n", #"\n");
//MessageBox.Show("OnUpdateRecordComplete SystemExeption Catch: " + error);
//It always goes on catch because we are not using MVC System
//It saves it anyways :P
//MessageBox.Show("OnCreateRecordComplete");
//syncContext.Send(new SendOrPostCallback(showErrorDetails), se);
}
}
You shouldn't have to do sleeping or waiting. My understanding is that the complete event handler is only called once async call returns.
Have you seen this sample? It should help to guide you in the right direction.
Sample: Create, Retrieve, Update and Delete Using the REST Endpoint with Silverlight

NotSupportedException in HttpWebRequest on Windows Phone 7

I have a Windows Phone 7 application built with silverlight. This application has been deployed. I've noticed in the log files that occasionally, my user's actions throw a "NotSupportedException". I have not been able to produce this. However, because of my logs, I know that it is happening in the Execute method shown here:
public void Execute()
{
try
{
// 1. Build the query
string serviceUrl = GetServiceUrl;
// 2. Asynchronously execute the query using HttpWebRequest
WebRequest request = HttpWebRequest.Create(serviceUrl);
request.BeginGetResponse(new AsyncCallback(ServiceRequest_Completed), request);
} catch (Exception ex)
{
LogException(ex, "1");
}
}
private void ServiceRequest_Completed(IAsyncResult result)
{
try
{
// 1. Get the response from the service call
WebRequest request = (WebRequest)(result.AsyncState);
WebResponse response = request.EndGetResponse(result);
// 2. Do stuff with response
}
catch (Exception ex)
{
LogException(ex, "2");
}
}
I know it is happening in the Execute method because the "1" is written in the log file instead of the "2" My question is, what would cause this? I looked at the MSDN documentation and it looks like I'm doing what I should be doing. Like I said, I can't reproduce it locally. But I do know that it is happening regularly by different users because of the log files.
There is a previous question with a very similar title - https://stackoverflow.com/questions/4053197/httpwebrequest-leads-me-to-system-notsupportedexception
The answer to that problem seems to have been using ServiceRequest_Completed instead of new AsyncCallback(ServiceRequest_Completed)

Handling image load exception gracefully

I'm loading user images using Silverlight 3.
Everything works fine and I can set the file stream to a BitmapImage and it gets rendered OK.
The problem is that if I try to load something that's not an image (like a .exe that's been renamed to .png) Silverlight crashes with a System.Exception that says "Catastrophic failure".
The MSDN documentation unhelpfully says that it should be so there msdn link and I should listen to the ImageFailed event (which never gets fired).
Am I missing something there or is the library broken when loading from a stream?
The code I've got loading the image from the source:
var openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "*.jpg;*.jpeg;*.png|*.jpg;*.jpeg;*.png";
openFileDialog.Multiselect = false;
var showDialog = openFileDialog.ShowDialog();
if (showDialog.HasValue && showDialog.Value)
{
using (var reader = openFileDialog.File.OpenRead())
{
var picture = new BitmapImage();
picture.DownloadProgress += (o, e) => System.Threading.SynchronizationContext.Current.Send((oo) => System.Windows.Browser.HtmlPage.Window.Alert("Download progress: " + e.Progress), null);
picture.ImageFailed += (o, e) => System.Threading.SynchronizationContext.Current.Send((oo) => System.Windows.Browser.HtmlPage.Window.Alert("Image failed: " + e.ErrorException), null);
picture.ImageOpened += (o, e) => System.Threading.SynchronizationContext.Current.Send((oo) => System.Windows.Browser.HtmlPage.Window.Alert("Image opened: " + e.OriginalSource), null);
picture.SetSource(reader); // BANG! here without any of the alerts showing up
}
}
That's weird, but you're right, it does behave that way, even on Silverlight 4.
There may be a better option, but one way I've found to work around these exceptions that can't otherwise be handled is to modify the App.Application_UnhandledException() method. This would work for you:
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
// Handle stupid image load exception. Can't think of a better way to do it -- sorry.
if (e.ExceptionObject is System.Exception && e.ExceptionObject.Message.Contains("HRESULT") && e.ExceptionObject.Message.Contains("E_UNEXPECTED"))
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Error loading image.");
});
e.Handled = true;
return;
}
// If the app is running outside of the debugger then report the exception using
// the browser's exception mechanism. On IE this will display it a yellow alert
// icon in the status bar and Firefox will display a script error.
if (!System.Diagnostics.Debugger.IsAttached)
{
// NOTE: This will allow the application to continue running after an exception has been thrown
// but not handled.
// For production applications this error handling should be replaced with something that will
// report the error to the website and stop the application.
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
It's a hack and I don't like it, but it's better than an unhandled exception.
BTW, you really ought to file a Connect bug on this behavior. It quite certainly fails the "Law of Least Astonishment". See Tim Heuer's post on how to get the bug filed: http://timheuer.com/blog/archive/2010/05/03/ways-to-give-feedback-on-silverlight.aspx

IPC windows service windows forms

I have an IPC problem. I have created into a windows service a NamedPipeServer:
serverPipe = new NamedPipeServerStream(Constants.PIPE_NAME, PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
Thread thread = new Thread(new ThreadStart(pipeWork));
thread.Start();
where pipeWork is
private static void pipeWork()
{
try
{
byte[] buffer = new byte[1024];
while (true)
{
if (!serverPipe.IsConnected)
serverPipe.WaitForConnection();
int nr = serverPipe.Read(buffer, 0, buffer.Length);
String str=Encoding.Default.GetString(buffer);
…
}
}
catch (Exception ex)
{
}
}
and into a Windows forms I have the client
clientPipe = new NamedPipeClientStream(".", PhotoServiceClassLibrary.Constants.PIPE_NAME, PipeDirection.InOut,PipeOptions.Asynchronous);
clientPipe.Connect();
clientPipe.ReadMode = PipeTransmissionMode.Message;
pipeThread=new Thread(new ThreadStart(pipeWork));
pipeThread.Start();
where pipeWork is
private void pipeWork()
{
try
{
while (true)
{
using (StreamReader sr = new StreamReader(clientPipe))
{
string message;
while ((message = sr.ReadLine()) != null)
{
…
}
}
}
}
catch (Exception ex)
{
}
}
I want when the service begin an action to disable a ContextMenuStrip from the windows forms, for that the service writes a message into a StreamWriter sw:
StreamWriter write = null;
write = new StreamWriter(serverPipe);
if (serverPipe.IsConnected)
{
write.Write(message);
write.Flush();
}
The code is correct because I created for testing another windows forms which implements the same things like the windows service and the communication between
windows forms pipe server -> windows forms pipe client is working well.
The problem is that the windows form - client pipe doesn't receive the message from windows service - server pipe.
I know that WCF can be a better idea but i want to understand why is not working at low-level IPC. Why? I've seen an very strange behavior. My service interact 2 times with the windows forms:
1.My service is designed for downloading some photos. When he begin download he sends a message to the windows forms to announcing him that.
2.When i stop the service he sends a message to windows forms and he stops also.
i've just discovered that both messages arrive at windows agent only after the service is stoped. Can someone explain why?
I hope this isn't your real code. It's good that you've got try/catch blocks around the code of your ThreadStart handlers (otherwise an exception would just quietly delete the thread). However, if you're not logging the exception in the catch block, then it's really just as bad.
You've got a mystery (server doesn't receive message), and you're hiding information (an exception has occurred). If you weren't hiding information, you might have the answer for your mystery (server doesn't receive message because an exception has occurred).
I'm trying to implement the same thing.
I noticed you're passing the PipeTransmissionMode.Message enumeration in the NamedPipeServerStream (serverPipe) constructor. That means the stream will contain strings.
But in pipeWork, you're reading them in as an array of bytes.
Look in the example in this article on MSDN:
http://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx

Resources