random types of errors occurring randomly in GTK# app using SOAP service async - soap

I'm developing a GTK# application using a SOAP service to get the data. Errors are occurring on retrieving items and putting them in a Gtk.ComboBox.
Types of errors seen:
gmem.c:170: failed to allocate x bytes, followed by SIGTRAP/SIGSEV/whatever
glibc detected * /usr/bin/mono: double free or corruption (fasttop): 0x00007f27100e85a0 *
Gdk:ERROR:gdkregion-generic.c:1110:miUnionNonO: assertion failed: (y1 < y2)
followed by SIGIOT
*just a SIGSEGV with a long stracktrace
I do also see these quite often:
(KvkManager:11471): Pango-WARNING **: Invalid UTF-8 string passed to pango_layout_set_text()
(KvkManager:11506): Gtk-WARNING **: gtktreemodel.c:2114: bad row reference, proxy has no outstanding row references
This is the main part of my code:
using System;
using Gtk;
using KvkWsProxy;
public partial class MainWindow: Gtk.Window
{
private KvkSoapServerService kvkProxy;
private NodeStore productsStore;
protected Gdk.PixbufAnimation loadingTrobber;
public MainWindow (): base (Gtk.WindowType.Toplevel)
{
Build ();
this.tabs.CurrentPage = 0;
this.loadingTrobber = new Gdk.PixbufAnimation("ajax-loader.gif");
this.productsStore = new Gtk.NodeStore(typeof(KvkManager.SimpleProductTreeNode));
this.kvkProxy = new KvkSoapServerService();
this.kvkProxy.getSimpleProductsCompleted += this.putProducts;
this.kvkProxy.getCollectionsCompleted += this.putProductCollections;
this.kvkProxy.getTypesCompleted += this.putProductTypes;
this.productsList.NodeStore = productsStore;
this.productsList.AppendColumn("Nummer", new Gtk.CellRendererText(), "text", 0);
this.productsList.AppendColumn("Naam", new Gtk.CellRendererText(), "text", 1);
this.productsList.AppendColumn("Prijs", new Gtk.CellRendererText(), "text", 2);
this.productsList.ShowAll();
this.getProductCollections();
this.getProductTypes();
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}
protected void putProductCollections(object sender, getCollectionsCompletedEventArgs args)
{
this.productCollectionsComboBox.Clear();
CellRendererText cell = new CellRendererText();
this.productCollectionsComboBox.PackStart(cell, false);
this.productCollectionsComboBox.AddAttribute(cell, "markup", 1);
ListStore store = new ListStore(typeof(int), typeof(string));
this.productCollectionsComboBox.Model = store;
store.AppendValues(-1, "<span font-style=\"italic\">alle collecties</span>");
foreach(Product_ProductCollection collection in args.Result)
{
store.AppendValues(collection.id, collection.name);
}
this.productCollectionsComboBox.Active = 0;
this.productCollectionsComboBox.Sensitive = true;
this.getCollectionsAnimation.Visible = false;
}
protected void putProductTypes(object sender, getTypesCompletedEventArgs args)
{
... like putProductCollections() ...
}
protected void OnSearchButtonClicked (object sender, System.EventArgs e)
{
this.productSearchButton.Sensitive = false;
this.searchAnimation.PixbufAnimation = this.loadingTrobber;
this.searchAnimation.Visible = true;
productsStore.Clear();
this.kvkProxy.getSimpleProductsAsync();
}
protected void putProducts(object sender, getSimpleProductsCompletedEventArgs args)
{
foreach(Product_SimpleProduct product in args.Result)
{
productsStore.AddNode(new KvkManager.SimpleProductTreeNode(product));
}
this.productSearchButton.Sensitive = true;
this.searchAnimation.Visible = false;
}
protected void getProductCollections()
{
this.productCollectionsComboBox.Sensitive = false;
this.getCollectionsAnimation.PixbufAnimation = this.loadingTrobber;
this.getCollectionsAnimation.Visible = true;
this.kvkProxy.getCollectionsAsync();
}
protected void getProductTypes()
{
... like putProductCollections() ...
}
protected void getProductSizegroups()
{
... like putProductCollections() ...
}
protected void getProductBrands()
{
... like putProductCollections() ...
}
}
You can download the whole project on http://home.vdslikke.net:8090/~johan/KvkManager.zip.
Versions of my software:
MonoDevelop 2.8.1
Mono 2.10.5 (tarball Mon Sep 5 19:35:47 UTC 2011) (64-bit)
GTK 2.24.8 (GTK# 2.12.0.0)
If there is any information you need to help me with this problem, please let me know.

I found out what I was doing wrong here
The thread that happens to run the event loop is said to "own" Gtk. This means that all Gtk operations should be perfomed from this thread and no other thread. Failure to restrict the use of Gtk to this thread will result in unpredictable behavior, and most often will lead to a crash.
After wrapping all GUI operations in Gtk.Application.Invoke() I get no errors anymore.

I solved the problem by not assigning the model before all the items were added, like this:
protected void putProductCollections(object sender, getCollectionsCompletedEventArgs args)
{
this.productCollectionsComboBox.Clear();
CellRendererText cell = new CellRendererText();
this.productCollectionsComboBox.PackStart(cell, false);
this.productCollectionsComboBox.AddAttribute(cell, "markup", 1);
ListStore store = new ListStore(typeof(int), typeof(string));
store.AppendValues(-1, "<span font-style=\"italic\">alle collecties</span>");
foreach(Product_ProductCollection collection in args.Result)
{
store.AppendValues(collection.id, collection.name);
}
this.productCollectionsComboBox.Model = store;
this.productCollectionsComboBox.Active = 0;
this.productCollectionsComboBox.Sensitive = true;
this.getCollectionsAnimation.Visible = false;
}
Now I only get GTK problems like wrong-drawn tabs and invisible animations once in a while. Then the following warning is printed in the console:
(KvkManager:13889): Gtk-CRITICAL **: IA__gtk_tree_row_reference_new: assertion `GTK_IS_TREE_MODEL (model)' failed
Any ideas on that?

Related

Polly Retry with RX Observable.Interval

I'm new to Polly and I'm trying to apply the Retry policy, so that I can have it manually handling the retry connection in case of IBMMQ connection issue.
Please, consider the following code:
public class ReconnectException : Exception
{
}
public class QueueMonitor : IObservable<Message>, IDisposable
{
private readonly MQQueue mqQueue;
private readonly MQQueueManager queueManager;
private readonly string queueName;
private IDisposable timer;
private readonly object lockObj = new object();
private bool isChecking;
private readonly TimeSpan checkingFrequency;
private readonly List<IObserver<Message>> observers;
private TimeSpan reconnectInterval;
private readonly IScheduler scheduler;
private readonly int maxReconnectCount;
private static readonly ILog Logger = LogProvider.For<AonQueueManager>();
private readonly Policy pollyPolicy;
public QueueMonitor(IConfiguration configuration, string queueName, IScheduler scheduler = null)
{
this.queueManager = QueueFactory.GetIstance(configuration);
this.queueName = queueName;
this.scheduler = scheduler ?? Scheduler.Default;
checkingFrequency = configuration.GetValue("checkingFrequency", new TimeSpan(0, 0, 5));
reconnectInterval = configuration.GetValue("reconnectInterval", new TimeSpan(0, 0, 5));
maxReconnectCount = configuration.GetValue("maxReconnectCount", 3);
observers = new List<IObserver<Message>>();
pollyPolicy = Policy.Handle<ReconnectException>().WaitAndRetry(maxReconnectCount, _ => TimeSpan.FromSeconds(2));
mqQueue = queueManager.AccessQueue(queueName,
MQC.MQOO_INPUT_AS_Q_DEF // open queue for input
+ MQC.MQOO_FAIL_IF_QUIESCING); // but not if MQM stopping
}
public void Start()
{
var x = pollyPolicy.ExecuteAndCapture(CreateTimer);
}
private void CreateTimer()
{
Logger.DebugFormat("Repeating timer started, checking frequency: {checkingFrequency}", checkingFrequency);
timer = Observable.Interval(checkingFrequency, scheduler).Subscribe(_ =>
{
lock (lockObj)
{
if (isChecking) return;
Logger.Log(LogLevel.Debug, () => "Listening on queues for new messages");
isChecking = true;
var mqMsg = new MQMessage();
var mqGetMsgOpts = new MQGetMessageOptions { WaitInterval = checkingFrequency.Milliseconds };
// 15 second limit for waiting
mqGetMsgOpts.Options |= MQC.MQGMO_WAIT | MQC.MQGMO_FAIL_IF_QUIESCING |
MQC.MQCNO_RECONNECT_Q_MGR | MQC.MQOO_INPUT_AS_Q_DEF;
try
{
mqQueue.Get(mqMsg, mqGetMsgOpts);
if (mqMsg.Format.CompareTo(MQC.MQFMT_STRING) == 0)
{
var text = mqMsg.ReadString(mqMsg.MessageLength);
Logger.Debug($"Message received : [{text}]");
Message message = new Message { Content = text };
foreach (var observer in observers)
observer.OnNext(message);
}
else
{
Logger.Warn("Non-text message");
}
}
catch (MQException ex)
{
if (ex.Message == MQC.MQRC_NO_MSG_AVAILABLE.ToString())
{
Logger.Trace("No messages available");
//nothing to do, emtpy queue
}
else if (ex.Message == MQC.MQRC_CONNECTION_BROKEN.ToString())
{
Logger.ErrorException("MQ Exception, trying to recconect", ex);
throw new ReconnectException();
}
}
finally
{
isChecking = false;
}
}
});
}
public IDisposable Subscribe(IObserver<Message> observer)
{
if (!observers.Contains(observer))
observers.Add(observer);
return new Unsubscriber(observers, observer);
}
public void Dispose()
{
((IDisposable)mqQueue)?.Dispose();
((IDisposable)queueManager)?.Dispose();
timer?.Dispose();
}
}
public class Unsubscriber : IDisposable
{
private readonly List<IObserver<Message>> observers;
private readonly IObserver<Message> observer;
public Unsubscriber(List<IObserver<Message>> observers, IObserver<Message> observer)
{
this.observers = observers;
this.observer = observer;
}
public void Dispose()
{
if (observer != null) observers.Remove(observer);
}
}
The problem I've is that when an exception is thrown inside the lamda ( throw new ReconnectException();), Polly doesn't catch it (and I understand why, since it's on another thread) and the application quits since it's on a different thread.
This code is a part of a library,so I don't know that if in every project the Global exceptions are correctly handed.
How do I get it "catched" by the Polly's code?
Thanks in advance
The code posted in the question applies the policy only to the act of creating the timer (the execution of CreateTimer()), not to the code executed by the timer (the lambda inside the .(Subscribe(_ => { }) call).
This is the same as the behaviour if the call to CreateTimer() was surrounded by a try { } catch { }. The catch would only cover the act of executing the CreateTimer() method, the creation of the timer.
For the Polly policy to govern exceptions thrown within the lambda, it needs to be applied within the lambda, to the relevant block/group of statements which are expected to throw the exception.
For example, you might code:
pollyPolicy.ExecuteAndCapture(() => mqQueue.Get(mqMsg, mqGetMsgOpts));
(with a policy configured to govern the particular MQException/s you want to handle).
Or you can apply the policy to a wider group of statements - just as with a try { } clause.
pollyPolicy.ExecuteAndCapture(() =>
{
// ...
mqQueue.Get(mqMsg, mqGetMsgOpts));
// ...
}

Curator ServiceCacheListener is triggered three times when a service is added

I am learning zookeeper and trying out the Curator framework for service discoveries. However, I am facing a weird issue that I have difficulties to figure out. The problem is when I tried to register an instance via serviceDiscovery, the cacheChanged event of the serviceCache gets triggered three times. When I removed an instance, it is only triggered once, which is the expected behavior. Please see the code below:
public class DiscoveryExample {
private static String PATH = "/base";
static ServiceDiscovery<InstanceDetails> serviceDiscovery = null;
public static void main(String[] args) throws Exception {
CuratorFramework client = null;
try {
// this is the ip address of my VM
client = CuratorFrameworkFactory.newClient("192.168.149.129:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
JsonInstanceSerializer<InstanceDetails> serializer = new JsonInstanceSerializer<InstanceDetails>(
InstanceDetails.class);
serviceDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetails.class)
.client(client)
.basePath(PATH)
.serializer(serializer)
.build();
serviceDiscovery.start();
ServiceCache<InstanceDetails> serviceCache = serviceDiscovery.serviceCacheBuilder()
.name("product")
.build();
serviceCache.addListener(new ServiceCacheListener() {
#Override
public void stateChanged(CuratorFramework curator, ConnectionState state) {
// TODO Auto-generated method stub
System.out.println("State Changed to " + state.name());
}
// THIS IS THE PART GETS TRIGGERED MULTIPLE TIMES
#Override
public void cacheChanged() {
System.out.println("Cached Changed ");
List<ServiceInstance<InstanceDetails>> list = serviceCache.getInstances();
Iterator<ServiceInstance<InstanceDetails>> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next().getAddress());
}
}
});
serviceCache.start();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.print("> ");
String line = in.readLine();
} finally {
CloseableUtils.closeQuietly(serviceDiscovery);
CloseableUtils.closeQuietly(client);
}
}
}
AND
public class RegisterApplicationServer {
final static String PATH = "/base";
static ServiceDiscovery<InstanceDetails> serviceDiscovery = null;
public static void main(String[] args) throws Exception {
CuratorFramework client = null;
try {
client = CuratorFrameworkFactory.newClient("192.168.149.129:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
JsonInstanceSerializer<InstanceDetails> serializer = new JsonInstanceSerializer<InstanceDetails>(
InstanceDetails.class);
serviceDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetails.class).client(client).basePath(PATH)
.serializer(serializer).build();
serviceDiscovery.start();
// SOME OTHER CODE THAT TAKES CARES OF USER INPUT...
} finally {
CloseableUtils.closeQuietly(serviceDiscovery);
CloseableUtils.closeQuietly(client);
}
}
private static void addInstance(String[] args, CuratorFramework client, String command,
ServiceDiscovery<InstanceDetails> serviceDiscovery) throws Exception {
// simulate a new instance coming up
// in a real application, this would be a separate process
if (args.length < 2) {
System.err.println("syntax error (expected add <name> <description>): " + command);
return;
}
StringBuilder description = new StringBuilder();
for (int i = 1; i < args.length; ++i) {
if (i > 1) {
description.append(' ');
}
description.append(args[i]);
}
String serviceName = args[0];
ApplicationServer server = new ApplicationServer(client, PATH, serviceName, description.toString());
server.start();
serviceDiscovery.registerService(server.getThisInstance());
System.out.println(serviceName + " added");
}
private static void deleteInstance(String[] args, String command, ServiceDiscovery<InstanceDetails> serviceDiscovery) throws Exception {
// in a real application, this would occur due to normal operation, a
// crash, maintenance, etc.
if (args.length != 2) {
System.err.println("syntax error (expected delete <name>): " + command);
return;
}
final String serviceName = args[0];
Collection<ServiceInstance<InstanceDetails>> set = serviceDiscovery.queryForInstances(serviceName);
Iterator<ServiceInstance<InstanceDetails>> it = set.iterator();
while (it.hasNext()) {
ServiceInstance<InstanceDetails> si = it.next();
if (si.getPayload().getDescription().indexOf(args[1]) != -1) {
serviceDiscovery.unregisterService(si);
}
}
System.out.println("Removed an instance of: " + serviceName);
}
}
I appriciate if anyone can please point out where I am doing wrong and maybe can share some good materials/examples so I can refer to. The official website and the examples on github does not help a lot.

Unstable application uses SqlDependency. Several states and errors

I have a windows application using SqlDependency running at separated thread pool, this application represents a log monitor UI get the latest rows added in a specific table in the database and view it in a DataGridView. You can see the application source code from this LINK, or follow this script.
const string tableName = "OutgoingLog";
const string statusMessage = "{0} changes have occurred.";
int changeCount = 0;
private static DataSet dataToWatch = null;
private static SqlConnection connection = null;
private static SqlCommand command = null;
public frmMain()
{
InitializeComponent();
}
private bool CanRequestNotifications()
{
// In order to use the callback feature of the
// SqlDependency, the application must have
// the SqlClientPermission permission.
try
{
SqlClientPermission perm = new SqlClientPermission(PermissionState.Unrestricted);
perm.Demand();
return true;
}
catch
{
return false;
}
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
// This event will occur on a thread pool thread.
// Updating the UI from a worker thread is not permitted.
// The following code checks to see if it is safe to
// update the UI.
ISynchronizeInvoke i = (ISynchronizeInvoke)this;
// If InvokeRequired returns True, the code
// is executing on a worker thread.
if (i.InvokeRequired)
{
// Create a delegate to perform the thread switch.
OnChangeEventHandler tempDelegate = new OnChangeEventHandler(dependency_OnChange);
object[] args = { sender, e };
// Marshal the data from the worker thread
// to the UI thread.
i.BeginInvoke(tempDelegate, args);
return;
}
// Remove the handler, since it is only good
// for a single notification.
SqlDependency dependency = (SqlDependency)sender;
dependency.OnChange -= dependency_OnChange;
// At this point, the code is executing on the
// UI thread, so it is safe to update the UI.
++changeCount;
lblChanges.Text = String.Format(statusMessage, changeCount);
// Reload the dataset that is bound to the grid.
GetData();
}
AutoResetEvent running = new AutoResetEvent(true);
private void GetData()
{
// Start the retrieval of data on another thread to let the UI thread free
ThreadPool.QueueUserWorkItem(o =>
{
running.WaitOne();
// Empty the dataset so that there is only
// one batch of data displayed.
dataToWatch.Clear();
// Make sure the command object does not already have
// a notification object associated with it.
command.Notification = null;
// Create and bind the SqlDependency object
// to the command object.
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
adapter.Fill(dataToWatch, tableName);
try
{
running.Set();
}
finally
{
// Update the UI
dgv.Invoke(new Action(() =>
{
dgv.DataSource = dataToWatch;
dgv.DataMember = tableName;
//dgv.FirstDisplayedScrollingRowIndex = dgv.Rows.Count - 1;
}));
}
}
});
}
private void btnAction_Click(object sender, EventArgs e)
{
changeCount = 0;
lblChanges.Text = String.Format(statusMessage, changeCount);
// Remove any existing dependency connection, then create a new one.
SqlDependency.Stop("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
SqlDependency.Start("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
if (connection == null)
{
connection = new SqlConnection("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
}
if (command == null)
{
command = new SqlCommand("select * from OutgoingLog", connection);
//SqlParameter prm =
// new SqlParameter("#Quantity", SqlDbType.Int);
//prm.Direction = ParameterDirection.Input;
//prm.DbType = DbType.Int32;
//prm.Value = 100;
//command.Parameters.Add(prm);
}
if (dataToWatch == null)
{
dataToWatch = new DataSet();
}
GetData();
}
private void frmMain_Load(object sender, EventArgs e)
{
btnAction.Enabled = CanRequestNotifications();
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
SqlDependency.Stop("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
}
The problem:
I have many situations of errors, (images in the first comment)
(No. 1):
I got this error dialog, and I don't know its reason.
(No. 2):
I got nothing in my grid view (No errors, and no data).
(No. 3):
I got only columns names and no rows, although the table has rows.
I need help please.
I may be wrong but a DataSet does not seem to have notification capability so the DataGridView may be surprised if you change it behind its back.
You could try to explicitly show your're changing the data source by first setting it to null:
dgv.DataSource = null;
dgv.DataSource = dataToWatch;
dgv.DataMember = tableName;
It's worth a try...

Android control the position of SurfaceView by WindowsManager.LayoutParams

How can I control the position of window?
I added the SurfaceView with WindowManager.LayoutParam into the WindowManager;
And I tried to change the x and y of WindowManager.LayoutParams in Thread;
But I only got the Wrong Thread Exception.
SurfaceViewDemoActivity .java
public class SurfaceViewDemoActivity extends Activity {
private MySurfaceView mySurfaceView;
private FloatingWindow floatingWindow;
private int x = 0;
private Thread t;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int imgId = R.drawable.bubble;
mySurfaceView = new MySurfaceView(this, imgId);
floatingWindow = new FloatingWindow(this, mySurfaceView, 0, 0);
t = new Thread(new Runnable(){
public void run() {
while (true) {
if (x > 150) x = 0;
//The problem is here.
floatingWindow.update(mySurfaceView, x, x);
x++;
}
}
});
t.start();
}
}
FloatingWindow .java
public class FloatingWindow {
private WindowManager windowManager;
private WindowManager.LayoutParams layoutParams;
private boolean hasViewAdded = false;
public final void update (View view, int coordX, int coordY) {
update(coordX, coordY);
update(view);
}
public final void update (View view) {
if ( isViewAdded() == true ) {
windowManager.updateViewLayout(view, layoutParams);
} else {
windowManager.addView(view, layoutParams);
setViewAdded(true);
}
}
private final void update (int coordX, int coordY) {
this.layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
this.layoutParams.x = coordX;
this.layoutParams.y = coordY;
}
private void updateSize (View view) {
int width = view.getWidth();
int height = view.getHeight();
this.layoutParams.width = width;
this.layoutParams.height = height;
}
public FloatingWindow (Context context, View view, int coordX, int coordY) {
init(context);
updateSize(view);
update(view, coordX, coordY);
}
private void init(Context context) {
this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
this.layoutParams = new WindowManager.LayoutParams();
this.layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
this.layoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
this.layoutParams.format = PixelFormat.TRANSPARENT;
}
protected boolean isViewAdded () {
return this.hasViewAdded;
}
protected void setViewAdded (boolean hasViewAdded) {
this.hasViewAdded = hasViewAdded;
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Log.txt
E/Trace(5041): error opening trace file: No such file or directory (2)
W/Trace(5041): Unexpected value from nativeGetEnabledTags: 0
I/Choreographer(5041): Skipped 128 frames! The application may be doing too much work on its main thread.
W/Trace(5041): Unexpected value from nativeGetEnabledTags: 0
W/dalvikvm(5041): threadid=11: thread exiting with uncaught exception (group=0xb5cff908)
E/AndroidRuntime(5041): FATAL EXCEPTION: Thread-252
E/AndroidRuntime(5041): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime(5041): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)
E/AndroidRuntime(5041): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:823)
E/AndroidRuntime(5041): at android.view.View.requestLayout(View.java:15468)
E/AndroidRuntime(5041): at android.view.View.setLayoutParams(View.java:10022)
E/AndroidRuntime(5041): at android.view.WindowManagerGlobal.updateViewLayout(WindowManagerGlobal.java:269)
E/AndroidRuntime(5041): at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:74)
E/AndroidRuntime(5041): at com.givemepass.surfaceview.FloatingWindow.update(FloatingWindow.java:27)
E/AndroidRuntime(5041): at com.givemepass.surfaceview.FloatingWindow.update(FloatingWindow.java:18)
E/AndroidRuntime(5041): at com.givemepass.surfaceview.SurfaceViewDemoActivity$1.run(SurfaceViewDemoActivity.java:33)
E/AndroidRuntime(5041): at java.lang.Thread.run(Thread.java:856)
W/Trace(5041): Unexpected value from nativeGetEnabledTags: 0
D/gralloc_goldfish(5041): Emulator without GPU emulation detected.
W/Trace(5041): Unexpected value from nativeGetEnabledTags: 0
I/Choreographer(5041): Skipped 671 frames! The application may be doing too much work on its main thread.
W/Trace(5041): Unexpected value from nativeGetEnabledTags: 0
W/Trace(5041): Unexpected value from nativeGetEnabledTags: 0
A/libc(5041): Fatal signal 11 (SIGSEGV) at 0xae3e1000 (code=1), thread 5057 (Thread-253)
I/Process(5041): Sending signal. PID: 5041 SIG: 9
After you added the 'SurfaceView' into 'WindowManager',
just change the 'x' and 'y' of WindowManager.LayoutParams.
If you had the 'Thread Exception' and message('Only the original thread that created a view hierarchy can touch its views.')like me, you can read Painless threading on 'Android Developers Blog'.
Thread t = new Thread(new Runnable(){
public void run() {
while (true) {
if ( x > 150 ) x = 0;
runOnUiThread(new Runnable() {
public void run() {
//Update the UI here.
floatingWindow.update(mySurfaceView, x, x);
}
});
x++;
}
}
});
You have to use Activity.runOnUiThread(Runnable action)
or create Handler in the UI thread and pass coordinates via message.
The GUI framework is not thread safe in the android.
So android's developers decided to notify everyone about mistake if somebody tries to work with UI from another thread.

Listen to msmq queue

Following the is the code I have for listening to messages from Windows form.
I have noticed that when I click on send it sends a message to MyQueue but at that time I was hoping the event mq_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e) should get called but it is not, in other words I am trying to subscribe to MyQueue from Windows form. Just wondering if I am missing something in the code:
public class Form1 : System.Windows.Forms.Form
{
public System.Messaging.MessageQueue mq;
public static Int32 j=0;
public Form1()
{
// Required for Windows Form Designer support
InitializeComponent();
// Queue Creation
if(MessageQueue.Exists(#".\Private$\MyQueue"))
mq = new System.Messaging.MessageQueue(#".\Private$\MyQueue");
else
mq = MessageQueue.Create(#".\Private$\MyQueue");
mq.ReceiveCompleted += new ReceiveCompletedEventHandler(mq_ReceiveCompleted);
mq.BeginReceive();
}
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnMsg_Click(object sender, System.EventArgs e)
{
// SendMessage(Handle, 1, 0, IntPtr.Zero);
System.Messaging.Message mm = new System.Messaging.Message();
mm.Body = txtMsg.Text;
mm.Label = "Msg" + j.ToString();
j++;
mq.Send(mm);
}
void mq_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
//throw new NotImplementedException();
}
private void btnRcv_Click(object sender, System.EventArgs e)
{
System.Messaging.Message mes;
string m;
try
{
mes = mq.Receive(new TimeSpan(0, 0, 3));
mes.Formatter = new XmlMessageFormatter(new String[] {"System.String,mscorlib"});
m = mes.Body.ToString();
}
catch
{
m = "No Message";
}
MsgBox.Items.Add(m.ToString());
}
}
See MSDN's example on how to use the ReceiveCompletedEventHandler .
They have a console app where the Main() does the same as your Form1(), but your handler doesn't have any code. You've said it doesn't call back into your event delegate, but perhaps check your queue name is correct on the constructor.
Consider using MSDN's sample code in a new console app to test your environment first, then go back to your WinForms code with any lessons learned.
private static void MyReceiveCompleted(Object source,
ReceiveCompletedEventArgs asyncResult)
{
MessageQueue mq = (MessageQueue)source;
Message m = mq.EndReceive(asyncResult.AsyncResult);
Console.WriteLine("Message: " + (string)m.Body);
mq.BeginReceive();
return;
}
If you want to inspect the queue and get a message on the click of a button, you can simply move the statement mq.BeginReceive(); to the btnRcv_Click() in place of .Receive();