2

Closed

Error when navigating Tree View too quickly

description

Error in Anolis Resourcer 0.8 Beta:
 
Spoke to W3bbo about it; I was navigating the program's loaded DLL components too quickly in tree view. (aka: I was being too rough with the program; I need to be more gentle with it.... Patience, I guess.)
 
W3bbo: yeah, you were just going too fast for it
W3bbo: I'll see if there's a way to queue-up the BackgroundWorker rather than interrupting it
W3bbo: in future, just be more gentle with it :p
 
-------------------------------------Debug report below-------------------------------------
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
 
************** Exception Text **************
System.InvalidOperationException: This BackgroundWorker is currently busy and cannot run multiple tasks concurrently.
at System.ComponentModel.BackgroundWorker.RunWorkerAsync(Object argument)
at Anolis.Resourcer.Controls.ResourceListView.ShowResourceType(ResourceType type) in C:\Documents and Settings\David\My Documents\Visual Studio Projects\Anolis\Anolis.Resourcer\Controls\ResourceListView.cs:line 112
at Anolis.Resourcer.MainForm.ListLoad(ResourceType type) in C:\Documents and Settings\David\My Documents\Visual Studio Projects\Anolis\Anolis.Resourcer\Forms\MainForm.Partial.cs:line 361
at Anolis.Resourcer.MainForm.__tree_AfterSelect(Object sender, TreeViewEventArgs e) in C:\Documents and Settings\David\My Documents\Visual Studio Projects\Anolis\Anolis.Resourcer\Forms\MainForm.cs:line 101
at System.Windows.Forms.TreeView.OnAfterSelect(TreeViewEventArgs e)
at System.Windows.Forms.TreeView.TvnSelected(NMTREEVIEW* nmtv)
at System.Windows.Forms.TreeView.WmNotify(Message& m)
at System.Windows.Forms.TreeView.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
 
 
************** Loaded Assemblies **************
mscorlib
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)

CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll

Anolis.Resourcer.Merged
Assembly Version: 0.8.3330.36117
Win32 Version: 0.8.0.0

CodeBase: file:///C:/Documents%20and%20Settings/Stanley/Desktop/Anolis.Resourcer.Merged.exe

System.Windows.Forms
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)

CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll

System
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)

CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll

System.Drawing
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)

CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll

System.Configuration
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)

CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll

System.Xml
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)

CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll

 
************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
 
For example:
 
<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>
 
When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.
Closed Apr 10, 2009 at 9:29 PM by W3bbo
I solved this by making the PopulateResourceType method check if the .CancelAsync method had been called. Additionally there are two layers of threads from ShowResourceType and PopulateResourceType.

comments

dexterinside wrote Mar 4, 2009 at 5:48 PM

I've experienced these quite alot some time ago... my solution for fixing it was implementing a pool of threads. In my app there are about 7-8 concurrent threads and some of course will require access to the UI.

When working with the tree from another thread you should go for something like if (this.InvokeRequired) ... and use BeginUpdate() and EndUpdate() when using data from the tree.

This is my ThreadMgr class, feel free to adapt it to your needs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Collections;

namespace LUR.Interop
{
public class ThreadMgr : IDisposable, IEnumerable
{
    private List<Thread> Pool = null;

    public ThreadMgr()
    {
        Pool = new List<Thread>();
    }

    public int Clean()
    {
        int Running = 0;
        if (Pool == null)
            return Running;

        for (int i = 0; i < Pool.Count; i++)
        {
            if (Pool[i].IsAlive)
                Running++;
            else
                Pool.Remove(Pool[i--]);
        }
        return Running;
    }

    public bool this[string Item, ThreadStart x]
    {
        set
        {

            Thread t = this[Item];
            if (t == null)
            {
                try
                {
                    if (x == null)
                        throw new System.ArgumentNullException();

                    t = this[Item] = new Thread(x);
                    t.TrySetApartmentState(ApartmentState.MTA);
                    if (value)
                        t.Start();
                }
                catch (System.ArgumentNullException)
                {
                    Console.WriteLine("ThreadMgr: null or malformed parameterized thread start invoked.");
                }
                catch (System.Threading.ThreadStateException msg)
                {
                    Console.WriteLine("ThreadMgr: failed " + msg.Message + " at " + msg.Source + " in " + Item + " context");
                }
                catch (Exception msg)
                {
                    Console.WriteLine("ThreadMgr: unrecoverable fault caused by " + msg.Message + " in " + msg.StackTrace);
                }
            }
            else
            {
                // Ionutz: testeaza-ma!
                MessageBox.Show(null, Item + " context is already locked or request is null; cannot instanciate.\n" +
                    "You may be trying to re-execute the same operation before waiting the previous attempt to complete", 
                    "Threading Manager", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
    }

    public Thread this[string Item]
    {
        get
        {
            if ((Pool != null) && (Pool.Count > 0))
            {
                foreach (Thread t in Pool)
                    if (t.Name == Item)
                        return t;
            }
            return null;
        }
        set
        {
            if (Pool == null)
                Pool = new List<Thread>();

            try
            {
                Pool.Add(value);
                value.Name = Item;
            }
            catch (Exception msg)
            {
                Console.WriteLine("ThreadMgr: " + msg.Message + "; " + value.Name + " override attempt with " + Item + " denied.");
            }
        }
    }

    public void Sync(string Item)
    {
        Thread t = this[Item];
        try
        {
            if (t.IsAlive)
                t.Join();
        }
        catch { }
    }

    #region IDisposable Members

    public void Dispose()
    {
        if ((Pool != null) && (Pool.Count > 0))
        {
            for (int i = 0; i < Pool.Count; i++)
            {
                if (Pool[i].IsAlive)
                    Pool[i].Abort();

                Pool.Remove(Pool[i--]);
            }
        }
    }

    #endregion

    public void Recycle(string id)
    {
        try
        {
            foreach (Thread Pooled in Pool)
            {
                if (Pooled.Name.Contains(id))
                {
                    Pooled.Abort();
                    break;
                }
            }
        }
        catch
        { }
    }


    #region IEnumerable Members

    public IEnumerator GetEnumerator()
    {
        foreach (Thread t in Pool)
        {
            yield return t;
        }
    }

    #endregion
}
}

wrote Mar 4, 2009 at 7:40 PM

wrote Mar 5, 2009 at 9:33 PM

wrote Mar 5, 2009 at 9:42 PM

wrote Apr 10, 2009 at 9:29 PM

wrote Feb 14, 2013 at 8:13 PM

wrote May 16, 2013 at 9:36 AM