Windows 7, SignalR2.
I have some HelloWorld SignalR code that works in one VS2013 project (Ie, my SignalR hello world playground).
When I add the same code to an existing application, SignalR threads "hang" in IIS "forever". This happens every single time.
My SignalR console looks like:
My perfMon counters look like this:
My worker process list looks like:
I'm after some tips on where to start debugging. In Java, I would take a thread dump and I could see what is going on fairly easily.
These threads are not visible in VS2013 when attached as a debugger.
There does not seem to be an equivalent in IIS/DotNet?
Here is my hub:
public class Ep1DataImportHub : Hub
{
public int recordsToBeProcessed = 100000;
public void DoLongOperation()
{
for (int record = 0; record <= recordsToBeProcessed; record++)
{
if (ShouldNotifyClient(record))
{
Clients.Caller.sendMessage(string.Format
("Processing item {0} of {1}", record, recordsToBeProcessed));
Thread.Sleep(10);
}
}
}
private static bool ShouldNotifyClient(int record)
{
return record % 10 == 0;
}
}
Here is my client, truncated to the simplest hanging scenario.
$(function () {
// Initialize the connection to the server
var realtimeNotifier = $.connection.ep1DataImportHub;
$.connection.hub.logging = true;
$.connection.hub.start();
})
There is lots of about SignalR hangs in IIS with SignalR 1, but I'm using SignalR 2.
Can someone please tell me how to start debugging what is going on. This tool looks interesting, but I have no idea what it is https://github.com/SignalR/SignalR/issues/1335 (https://github.com/SignalR/SignalR/issues/1335)
Here is the Managed call stack of one of the stuck threads
System_Web_ni!DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, Boolean, Boolean ByRef)+8f
[[InlinedCallFrame] (System.Web.Hosting.UnsafeIISMethods.MgdExplicitFlush)] System.Web.Hosting.UnsafeIISMethods.MgdExplicitFlush(IntPtr, Boolean, BooleanByRef)
System_Web_ni!System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()+20
System_Web_ni!System.Web.HttpResponse.Flush(Boolean, Boolean)+c3
System_Web_ni!System.Web.HttpWriter.WriteFromStream(Byte[], Int32, Int32)+a0
Microsoft.Owin.Host.SystemWeb.CallStreams.DelegatingStream.Write(Byte[], Int32, Int32)+3a
Microsoft.Owin.Host.SystemWeb.CallStreams.OutputStream.Write(Byte[], Int32, Int32)+3b
Microsoft.AspNet.SignalR.Owin.ServerResponse.Write(System.ArraySegment`1)+24
Microsoft.AspNet.SignalR.Hosting.ResponseExtensions.End(Microsoft.AspNet.SignalR.Hosting.IResponse, System.String)+c8
Microsoft.AspNet.SignalR.PersistentConnection+d__f.MoveNext()+180
mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+285
mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+9
mscorlib_ni!System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run()+a4
System_Web_ni!System.Web.Util.SynchronizationHelper.SafeWrapCallback(System.Action)+b4
mscorlib_ni!System.Threading.Tasks.Task.Execute()+6e
mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+285
mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+9
mscorlib_ni!System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)+250
mscorlib_ni!System.Threading.Tasks.Task.ExecuteEntry(Boolean)+85
mscorlib_ni!System.Threading.ThreadPoolWorkQueue.Dispatch()+1ea
[[DebuggerU2MCatchHandlerFrame]]
[[ContextTransitionFrame]]
[[DebuggerU2MCatchHandlerFrame]]
Do you happen to have an Application_PreSendRequestHeaders method defined or are you in some other way attached to the HttpApplication.PreSendRequestHeaders event?
I ask, because this seems to be the same issue reported here. For at least some people on that thread, removing the PreSendRequestHeaders event handler resolved the issue.
While we recommend you never use the PreSendRequestHeaders event, we are actively working on this issue so we can get a fix out for 2.1.1.
If you are not attaching to the PreSendRequestHeaders event, we (the SignalR team) could use your help. So far, we have not been able to reproduce this issue without attaching to the PreSendRequestHeaders event. If you could provide us with an application that doesn't attach to this event, yet still hangs in this manner, we would greatly appreciate it.
The previous version of SignalR (2.0.3), did not make requests to /signalr/start and does not experience this hang. So you can temporarily work around this issue by downgrading from SignalR 2.1.0 to 2.0.3 until 2.1.1 is released.
We traced this problem back to Glimpse.ASPNet. It attaches itself to PreSendRequestHeaders. Therefore, if you use Glimpse.ASPNet with SignalR, you might find you get threads locking up "forever".
Removing Glimpse.AspNet fixes the problem
Related
Trying to push a message into UI and receive some result to return in synchronous way from web-service.
Method code goes as follows.
[OperationContract]
public string DecypherCaptcha(string captcha)
{
var connection = new HubConnection("http://localhost:51806");
IHubProxy hub = connection.CreateHubProxy("robo");
string decaptcha = null;
hub.On("captchaDecyphered", decyphered =>
{
decaptcha = decyphered;
});
connection.Start().Wait();
hub.Invoke<string>("DecypherCaptcha", new object[] { captcha });
return decaptcha;
}
The issue is that method finishes before value is obtained from hub's captchaDecyphered. However the expression { decaptcha = decyphered; } triggers fine from server after method exits.
Adding ManualResetEvent flag and WaitOne() for it doesn't solve the problem freezing the execution and preventing hub.On("captchaDecyphered" from firing.
Any ideas how to synchronize this?
UPDATE#1 Small notice. Cannot avoid using the intermediate synchronous WCF web-service acting as SignalR client, because of pretty specific robots sitting behind, which are able to interact with outer world only by calling webservices synchronously. Basically in this scenario when robot faces captcha it calls the web-service passing it via SignalR to UI for manual recognition.
UPDATE#2 Thanks to #Ken's inspiring advice got it working by enclosing the connection establishing and hub method invocation into separate 'Thread' followed by waiting with 'ManualResetEvent':
new Thread(() =>
{
connection.Start().Wait();
hub.Invoke<string>("DecypherCaptcha", new object[] { captcha });
}).Start();
sync.WaitOne();
Have previously been trying to start from 'Task' supposing it would run on separate thread implicitly, but with no luck.
You could have the DecypherCaptcha hub method on the SignalR server return the deciphered captcha as a Task<string> instead on invoking captchaDecyphered.
You may want to use a TaskCompletionSource to help you create the appropriate task. Basically you could call tcs.SetResult(deciphered) and return tcs.Task instead of calling Clients.Caller.captchaDecyphered(deciphered).
Then your client-side code code would simply be:
[OperationContract]
public string DecypherCaptcha(string captcha)
{
var connection = new HubConnection("http://localhost:51806");
IHubProxy hub = connection.CreateHubProxy("robo");
connection.Start().Wait();
return hub.Invoke<string>("DecypherCaptcha", captcha).Result;
}
You've got several options.
(1) Spin off the request to the SignalR hub onto a separate thread, probably using the static ThreadPool class, and then add in all the ManualResetEvent stuff. That way it won't block when you're waiting on the SignalR method to return.
(2) Make the DecypherCaptcha method asynchronous. It looks to me like the DecypherCaptcha() is intended to be a WCF method that in turn wraps a SignalR method. If that's the case, forgetting for a moment whether this is a wise approach, you could still call a WCF method on the client when the captchaDecyphered SignalR method completes. But if it's not intended to be a WCF method, then you could have DecypherCaptcha() either (a) return a Task<T>, and only flag the Task to be complete when the captchaDecyphered completes; or (b) pass in a Func<T> as a continuation parameter, and call that when the captchaDecyphered completes.
In general, one of the things that makes asynchronous programming difficult is that except for the very top-level method, you generally need to make every method that calls an asynchronous method itself asynchronous, all the way up and down the stack, either through the Async pattern (nasty), or continuation passing (better) or through a Task object + async/await (probably best). So adding in a single asynchronous method often results in significant changes to your application, all the way through. That's one of the many reasons why the new async and await keywords in .NET 4.5 are so helpful, because they help to encapsulate the necessary changes when you start making your application asynchronous.
You can use the generic Invoke method where you can specify the type of result you expect. With the method you CAN use .Result to wait for the result.
string result = IHubProxy.Invoke<string>("GetString").Result;
I'm facing a problem after the migration from Spring 2.5, Flex 3.5, BlazeDS 3 and Java 6 to Spring 3.1, Flex 4.5, BlazeDS 4 and Java 7. I've declared a ClientFeed in order to send a sort of "alarm" messages to the flex client. There are three methods those alarms are sent. The first one is via snmp traps, a thread is started and wait for any trap, as one is received an alarm will be sent. The second method is via a polling mechanism, at the beginning of the web application a thread is started and will poll after a constant amount of time the alarms and send them to the client. The third method is the explicit poll command from the user, this will call a specific function on the dedicated service. This function uses then the same algorithm used in the second methods to perform a poll and shall send those alarms to the client.
The problem is that after the migration the first two methods are working without a problem, but the third one doesn't. I suspect there is a relation with the threads. Is there any known issue between messagetemplate and the threads with the new frameworks ?
Here is a snapshot of the used client feed:
#Component
public class ClientFeed {
private MessageTemplate messageTemplate;
#Autowired
public void setTemplate(MessageTemplate messageTemplate) {
this.messageTemplate = messageTemplate;
}
public void sendAlarmUpdate(final Alarm myAlarm) {
if (messageTemplate != null) {
System.out.println("Debug Thread: " + Thread.currentThread().getName());
messageTemplate.send(new AsyncMessageCreator() {
public AsyncMessage createMessage() {
AsyncMessage msg = messageTemplate.createMessageForDestination("flexClientFeed");
msg.setHeader("DSSubtopic", "Alarm");
msg.setBody(myAlarm);
return msg;
}
});
}
}
}
By the three methods I reach this piece of code and the displayed thread name are respectively: "Thread-14", "Thread-24" and "http-bio-80-exec-10".
I solved the problem by creating a local thread on the server to perform the job. Therewith the client feed is called via this new created thread instead of the http-thread.
I'm studying right now the bluetooth Android API, and I ran into the BluetoothChat example.
http://developer.android.com/resources/samples/BluetoothChat/index.html
It contains many errors, first of all the simple fact that it uses API 11 but manifest does not force this minimum API.
Other interesting thing is the use of synchronized keyword on Activity lifecycle methods, like on onResume:
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
Why this keyword is used there? Is there any reasonable explanation, or simply the one who wrote the code didn't know that onResume will be called always by the same thread? Or I miss something?
Thank you in advance!
This seems to be a pretty old question, but here's what I think may be going on:
My guess is that it wants to be careful about when "dialogs" return. The BluetoothChat example uses dialogs (as well as an overlay dialog-like activity) for enabling Bluetooth, enabling discovery, and initiating pairing/connections.
I don't know this for sure but I suspect there was a bug where different threads were returning to the main Activity and caused confusion as to how to handle onResume.
What they probably should have done is synchronize a block on an object and used flags to determine the state. That way the intention, state and functionality are more clear -- and the app knows what it should do in onResume;
something like this maybe:
//class fields
private Object myLockObj = new Object();
private boolean isPausedForPairing = false;
public void onResume()
{
super.onResume();
synchronized (myLockObj)
{
if (isPausedForPairing)
{
//handle a "pairing" onResume
}
}
}
However, due to it being an example app, they may have decided to go with something more simple. Example apps don't always follow convention because the idea is to demonstrate the particular code needed for the example. Sometimes following convention might add a lot of "distracting" code. Whether or not you agree with that is up to you though.
I am writing an app that uses the serial port exposed by the SerialPort class in mono. What I have written so far works perfect in windows, however in linux the DataReceived event handler is never entered, so I cannot receive any data form my device. I have declared the event handler as follows:
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
Basically I am exploring good cross-platform options and this is a deal-breaker. Any advise on how to fix this or what is going on?
Edit-
I should also point out that I have tested the serial port and device on linux with other applications and all appears to be working.
Maybe it has changed lastly, but as far as I know, events are not currently implemented in Mono's serial port. You have to make another thread in any flavour to read data from serial port, which happens in blocking manner. Try it and tell if it worked.
On Antanas Veiverys blog you can find two possible ways to solve it.
(2012) By adjusting the mono source code.
http://antanas.veiverys.com/enabling-serialport-datareceived-event-in-mono/
(2013) By not touching the mono source but solving the issue in a derived class.
http://antanas.veiverys.com/mono-serialport-datareceived-event-workaround-using-a-derived-class/
(2014)
However, I encourage you to read Ben Voigts blog post where he ignores using the DataReceivedEvent and instead used the BaseStream async BeginRead/EndRead functions to read data from the serial port.
http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport#comment-840
Implementing and using the given code sample works on both Windows/Unix, so I have tested. And it is more elegant than using the blocking Read() function in a threaded fashion.
mono does not support Event for serialport.
It is shown on mono's website
I have the same problem with SerialPort.DataReceived. Konrad's advice.
using System.IO.Ports;
using System.Threading;
namespace Serial2
{
class MainClass
{
public static void Main(string[] args)
{
Thread writeThread = new Thread(new ThreadStart(WriteThread));
Thread readThread = new Thread(new ThreadStart(ReadThread));
readThread.Start();
Thread.Sleep(200); // TODO: Ugly.
writeThread.Start();
Console.ReadLine();
}
private static void WriteThread()
{ // get port names with dmesg | grep -i tty
SerialPort sp2 = new SerialPort("/dev/ttyS5", 115200, Parity.None, 8, StopBits.One);
sp2.Open();
if(sp2.IsOpen)
Console.WriteLine("WriteThread(), sp2 is open.");
else
Console.WriteLine("WriteThread(), sp2 is open.");
sp2.Write(" This string has been sent over an serial 0-modem cable.\n"); // \n Needed (buffering?).
sp2.Close();
}
private static void ReadThread()
{
SerialPort sp = new SerialPort("/dev/ttyS4", 115200, Parity.None, 8, StopBits.One);
sp.Open();
if(sp.IsOpen)
Console.WriteLine("ReadThread(), sp Opened.");
else
Console.WriteLine("ReadThread(), sp is not open.");
while(true)
{
Thread.Sleep(200);
if(sp.BytesToRead > 0)
{
Console.WriteLine(sp.ReadLine());
}
}
}
}
}
I have a Silverlight application that uses WCF services and also uses the Wintellect Power Threading library to ensure logic executes fully before the application continues. This is achieved by calling back to the application using delegates so it can continue after the service call has completely finished.
I wish to achieve the same thing in another part of my application but without the use of callbacks e.g. call method that uses WCF service to say load an object from the database, wait for this to return and then return the Id of the object from the original method called.
The only way I could see to do this was to carry out the call to the WCF service in a helper library which loads the object on a different thread and the original method would keep checking the helper library (using static variables) to wait for it to complete and then return it.
Is this the best way to achieve this functionality? If so here are details of my implementation which is not working correctly.
public class MyHelper
{
private static Thread _thread;
private static User _loadedObject;
public static GetUser()
{
return _loadedObject;
}
public static void LoadObject(int userId)
{
_loadedObject = null;
ParameterizedThreadStart ts = new ParameterizedThreadStart(DoWork);
_thread = new Thread(ts);
_thread.Start(userId);
}
private static void DoWork(object parameter)
{
var ae = new AsyncEnumerator();
ae.BeginExecute(DoWorkWorker(ae, Convert.ToInt32(parameter)), ae.EndExecute);
}
private static IEnumerator<Int32> DoWorkWorker(AsyncEnumerator ae, int userId)
{
// Create a service using a helper method
var service = ServiceHelper.GetService<IUserServiceAsync>();
service.BeginGetUserById(userId, ae.End(), null);
yield return 1;
_loadedObject = service.EndGetUserById(ae.DequeueAsyncResult());
_thread.Abort();
}
}
My method then is:
public int GetUser(int userId)
{
MyHelper.LoadObject(userId);
User user = MyHelper.GetUser();
while (user == null)
{
Thread.Sleep(1000);
user = MyHelper.GetUser();
}
return user.Id;
}
The call to the get the user is executed on a different thread in the helper method but never returns. Perhaps this is due to the yield and the calling method sleeping. I have checked the call to get the user is on a different thread so I think everything should be kept separate,
The whole construct you are using does not match current best practices of Silverlight. In Silverlight your data access methods (via WebServices of course) are executed asynchronously. You should not design around that, but adapt your design accordingly.
However calling services sequentially (which is different than synchonously) can be valid in some scenarios. In this blog post I have shown how to achieve this by subscribing the Completed event of the remote call and block the UI in the meantime, with which the workflow looks and feels like normal async calls.
I believe calls to the server from Silverlight apps use events that fire on the UI thread; I think that's part of the Silverlight host environment in the browser and can't be worked around. So trying to call back to the server from another thread is never going to end well. If you are waiting in program code in the UI thread, your never going to get the call result events from your WCF calls.
You can simulate a synchronous call from a non-UI thread with a callback on the UI thread, but that is probably not what you want. It's better to bite the bullet and make your program logic work with the async calls Silverlight gives you.
If you code against the Interface created for your service reference you can call the Begin and End methods 'synchronously' for each one of your service calls, we then pass in an Action<T> to execute after the End methods has completed. Take note that you have to do this from a dispatcher. This is very close to making a synchronous call as the code to run after the call is still written where the call is made, and it executes after the service call is completed. It does however involve creating wrapper methods but we also worked around that by hiding our wrappers and generating them automatically. Seems like a lot of work but isn't, and ends up being more elegant than all the event handlers etc. Let me know if you need more info on this pattern