[SOLVED] Timer Causing a Connection to be Opened Twice

Answered Closed
0
1

Hi,

I have an application that uses a Timer to do a refresh every 10 seconds. The refresh calls a Refresh method, which uses an object with a pre-established connection to our database to Fetch all necessary rows, and then display them in a DataGridView.

I also have a manual refresh button on the DataGridView that also calls the Refresh method. If I manage to click the manual refresh button at the same time that the Timer ticks, and causes an automatic refresh, I run into an issue where two threads are trying to perform the Fetch at the same time, and get an exception because the pre-established connection is already in use.

Is there a way to force the Timer to run on the UI thread, so that this does not happen?

I have already attempted using Application.StartTask to dispatch a task on the UI thread that would perform the refresh, but this still causes the re-entrant problem. Dispatching the task on the UI thread, from what I am seeing, causes Initialization/Display events to kick off, which also call the same pre-established connection to do an initial fill of the DataGridView.

I also tried saving the current SynchronizationContext during Initialization, and then dispatching the Timer event to the UI SynchronizationContext with the same result as using Application.StartTask.

Thanks & let me know if I did not give enough detail!

-Jace

  • You must to post comments
Best Answer
0
0

See attached.

Wisej can push the updates to the browser (when in a websocket connection) but the grid has an internal threshold for the number of updated cells/rows that when passed it triggers a data reload to minimize the network traffic. The data reload is processed in parallel to user events.

Also, we have a new experimental option in Wisej to create a server side thread timer using Application.StartTimer(). It starts a server side timer that calls your callback in context. However it’s up to your code to manage the timer: dispose when the session terminates, etc. The sample attached uses a client timer, didn’t turn off websocket but it should work the same way since data read requests are always over http.

 

  • You must to post comments
Great Answer
0
0

Did you use a Wisej.Web.Timer or a thread timer?

If you used a Wisej.Web.Timer, it fires an event on the client which is dispatched to the server as a client event. Exactly like a click. All events coming in from the browser in Wisej are synchronized. There is no UI thread in Wisej. Each request coming from the browser is assigned a thread from the thread pool and there synchronized in the order they come in.

If you used a system timer (thread timer) it’s a different issue.

Let me know.

  • Jace Plute
    Hey Luca, thanks for the response. I am using a Wisej Timer. Your response prompted me to look at the parallel call stacks when I get the connection error again, It looks like the error comes from a call originating from IWisejComponent.Event -> Timer.OnTick and a call originating from IWisejDataStore.OnDataRead -> DataGridView.OnWebDataRead both trying to use the connection. I think the latter call must be because I am rebuilding the list on the refresh? Is there any way to circumvent this? I managed to get a fix in place using a semaphore-like structure around the method using the connection, but is there a better practice? Thanks again for your help!
  • You must to post comments
0
0

The data read request is processed in parallel. That’s correct. You can protect (synchronize) the specific function using a lock block. You can lock a session object.

I’ll send you sample code.

BTW, you have a TP account with us and can log issues directly on your github private repository at iceteagroup.

  • You must to post comments
Showing 3 results