That means that repl.EndSynchronize(ar); is called from your UI thread, so
you are blocking your UI thread. Worse, you call Invoke(which is blocking
until the message has ben handled by the UI thread, but this one is
blocked - that means deadlock.
You should never call any wait function (ar.AsyncWaitHandle.WaitOne();) on
the UI thread, so move this whole code to a separate thread.
Willy.
[quoted text, click to view] "Steve B." <steve_beauge@com.msn_swap_com_and_msn> wrote in message
news:OxjlujBKGHA.740@TK2MSFTNGP12.phx.gbl...
| I've made some search and found I can use the "BeginXXX" and "EndXXX" to
| reach my goal. Any exception thrown in the second thread should be raised
on
| the EndXXX call, doesn't it ?
|
| But with this approach, when I call listbox1.Invoke(...) to update the
value
| of a litsbox in its thread, the code hangs on the line
listbox1.Invoke(...).
|
| My updated code is this one :
|
| try
| {
| if (!File.Exists(GlobalConnection.Default.LocalDataBaseFile))
| this.InitLocalDatabase(false);
| //repl.Synchronize();
| IAsyncResult ar = repl.BeginSynchronize(
| new AsyncCallback(this.SyncCompletedCallBack),
| new OnStartTableUpload(this.OnStartTableUploadCallBack),
| new OnStartTableDownload(this.OnStartTableDownloadCallBack),
| new OnSynchronization(this.OnSynchronizationCallBack),
| repl
| );
| ar.AsyncWaitHandle.WaitOne();
| repl.EndSynchronize(ar);
| }
| catch (SqlCeException exc)
| {
| ... Custom exception handling ...
| }
|
| The 4 delegated methods throw an event in my replication manager that is
| handled by the application
|
| void Default_SynchronizationStep(object sender,
SynchronizationStepEventArgs
| e)
|
| {
|
| this.Invoke(
|
| new AddDelegate(Add),
|
| "SynchronizarionStep : " + e.PercentComplete.ToString() + "%"
|
| ); // this line hangs the application
|
|
| }
|
| If I replace the Invoke Method by BeginInvoke method, it does not hangs,
but
| the listbox update its value only after the EndSynchronize has been
called.
|
| Thanks,
| Steve
|
| "Chris Tacke, MVP" <ctacke@spamfree-opennetcf.org> a écrit dans le message
| de news: uOMGJNBKGHA.3936@TK2MSFTNGP10.phx.gbl...
| > Since the caller is asynchronous, an exception in the thread can't be
| > detected to be at any specific point. The thread should raise an
internal
| > event that the primary thread is listening to to notify it that the
| > exception has occurred.
| >
| > -Chris
| >
| >
[quoted text, click to view] | > "Steve B." <steve_beauge@com.msn_swap_com_and_msn> wrote in message
| > news:%234luPz$JGHA.1676@TK2MSFTNGP09.phx.gbl...
| >> Hi,
| >>
| >> I'm building a device application that works on two threads (using VS
| >> 2005 and CF 2.0).
| >>
| >> I'm using threads because one of my operations is quite long (up to 30
| >> minutes or more), and I want to display the user a progress bar and
| >> messages in a listbox.
| >> This operation is a Sql Mobile Merge replication, but I suppose
handling
| >> exceptions in other theads is quite standard.
| >>
| >> I've a class that handle the replication, and below is a part of the
code
| >> I use.
| >> I'd like to know how to correctly handle any exception in the second
| >> thread ?
| >>
| >> The "DoSynchronize" method must exit only when the replication has
| >> finished. I use BeginSynchronize to enable firing events. If an
exception
| >> occurs while replicating, I want the exception to be thrown to the
| >> DoSynchronize calling method.
| >>
| >> What have I to do ?
| >>
| >> Below is the partial code of my replication manager [1] and the form
that
| >> should display the progression (in a list box)[2]
| >>
| >> Thanks,
| >> Steve
| >>
| >> [1]
| >> public class SqlCeReplicationManager
| >> {
| >> private static System.Threading.AutoResetEvent _isSync = new
| >> System.Threading.AutoResetEvent(false);
| >>
| >> #region Synchronization progression monitoring
| >>
| >> /// <summary>
| >> /// Notify when a table is downloaded
| >> /// </summary>
| >> public event EventHandler<TableTransferedEventArgs> TableDownloaded;
| >> /// <summary>
| >> /// Notify when a table is uploaded
| >> /// </summary>
| >> public event EventHandler<TableTransferedEventArgs> TableUploaded;
| >> /// <summary>
| >> /// Notify the progression of the synchronization
| >> /// </summary>
| >> public event EventHandler<SynchronizationStepEventArgs>
| >> SynchronizationStep;
| >> /// <summary>
| >> /// Notify when the synchronization complete
| >> /// </summary>
| >> public event EventHandler<SynchronizationCompletedEventArgs>
| >> SynchronizationCompleted;
| >>
| >> #endregion
| >>
| >> private void DoSynchronize(SqlCeReplication repl)
| >> {
| >> //repl.Synchronize();
| >> repl.BeginSynchronize(
| >> new AsyncCallback(this.SyncCompletedCallBack),
| >> new OnStartTableUpload(this.OnStartTableUploadCallBack),
| >> new OnStartTableDownload(this.OnStartTableDownloadCallBack),
| >> new OnSynchronization(this.OnSynchronizationCallBack),
| >> repl
| >> );
| >> _isSync.WaitOne();
| >> }
| >> private void SyncCompletedCallBack(IAsyncResult ar)
| >> {
| >> ((SqlCeReplication)ar.AsyncState).EndSynchronize(ar);
| >> if (this.SynchronizationCompleted != null)
| >> {
| >> this.SynchronizationCompleted(
| >> this,
| >> new SynchronizationCompletedEventArgs(new
| >> ChangesStats((SqlCeReplication)ar.AsyncState))
| >> );
| >> }
| >> _isSync.Set();
| >> }
| >> private void OnStartTableUploadCallBack(
| >> IAsyncResult ar,
| >> string tableName
| >> )
| >> {
| >> if (this.TableUploaded != null)
| >> {
| >> this.TableUploaded(
| >> this,
| >> new TableTransferedEventArgs(tableName)
| >> );
| >> }
| >> }
| >> private void OnStartTableDownloadCallBack(
| >> IAsyncResult ar,
| >> string tableName
| >> )
| >> {
| >> if (this.TableDownloaded != null)
| >> {
| >> this.TableDownloaded(
| >> this,
| >> new TableTransferedEventArgs(tableName)
| >> );
| >> }
| >> }
| >> private void OnSynchronizationCallBack(
| >> IAsyncResult ar,
| >> int percentComplete
| >> )
| >> {
| >> if (this.SynchronizationStep != null)
| >> {
| >> this.SynchronizationStep(
| >> this,
| >> new SynchronizationStepEventArgs(percentComplete)
| >> );
| >> }
| >> }
| >> private void CancelSynchronize()
| >> {
| >> GetReplicationObject().CancelSynchronize();
| >> _isSync.Set();
| >> }
| >>
| >> }
| >>
| >> public partial class frmSqlRepl : Form
| >> {
| >> public frmSqlRepl()
| >> {
| >> InitializeComponent();
| >>
| >> SqlCeReplicationManager1.TableUploaded +=
| >> new EventHandler<TableTransferedEventArgs>(
| >> SqlCeReplicationManager1_TableUploaded
| >> );
| >> SqlCeReplicationManager1.TableDownloaded +=
| >> new EventHandler<TableTransferedEventArgs>(
| >> SqlCeReplicationManager1_TableDownloaded
| >> );
| >> SqlCeReplicationManager1.SynchronizationStep +=