locked
Why when using async.task,await it's not working when trying to report progress from another class ? RRS feed

  • Question

  • Form1:

    Inside the button1_click if i'm using only the for loop:

    for (int i = 0; i < 100; i++)
                {
                    // call a async method to process
                    await ProcessObject(i);
                }


    It will work fine. I can also if i want to use the Thread.Sleep in this part and it will work fine too:

    await Task.Run(() =>
                {
                    //Will be run in ThreadPool thread
                    //Do whatever cpu bound work here
                    //Thread.Sleep(1000);
                });


    But now i want to report the progress(The number of items that are adding in real time to the windowSnaps variable.

    So i'm using the two lines instead the for loop:

    this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());
    await ProcessObject(WindowSnap.windowSnaps.Count);


    But it's not reporting at all.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace MinimizeCapture
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void buttonSnap_Click(object sender, EventArgs e)
            {
                this.listBoxSnap.Items.Clear();
                this.pictureBoxSnap.Image = null;
            }
    
            private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
            {
                WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
    
                this.pictureBoxSnap.Image = snap.Image;
            }
    
            private void buttonSnapHandle_Click(object sender, EventArgs e)
            {
                try
                {
                    WindowSnap snap = WindowSnap.GetWindowSnap((IntPtr)Convert.ToInt32(this.textBoxHandle.Text), true);
                    if (snap.Image != null)
                        this.pictureBoxSnap.Image = snap.Image;
                }
                catch { MessageBox.Show("Wrong Handle (note:handle must be entered as decimal (hex is not acceptable)"); }
            }
    
            #region Update for 10 October 2007
    
            private void checkBoxForceMDI_CheckedChanged(object sender, EventArgs e)
            {
                WindowSnap.ForceMDICapturing = (sender as CheckBox).Checked;
            }
    
    
            #endregion
    
            private async void button1_Click(object sender, EventArgs e)
            {
                // almost 15 process
                /*for (int i = 0; i < 100; i++)
                {
                    // call a async method to process
                    await ProcessObject(i);
                }*/
                this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());
                await ProcessObject(WindowSnap.windowSnaps.Count);
            }
    
            private async Task ProcessObject(int process)// <--Note the return type
            {
                // my code is here with some loops
                await Task.Run(() =>
                {
                    //Will be run in ThreadPool thread
                    //Do whatever cpu bound work here
                    //Thread.Sleep(1000);
                });
    
                //At this point code runs in UI thread
                //process.Progress++;
    
                // feedback to UI
                UpdateRow(process);
            }
    
            private void UpdateRow(int process)
            {
                label2.Text = process.ToString();
            }
        }
    }


    The WindowSnap.cs class code:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace MinimizeCapture
    {
    
        class WindowSnap
        {
    
            #region Win32
    
            private const string PROGRAMMANAGER = "Program Manager";
            private const string RUNDLL = "RunDLL";
    
            private const uint WM_PAINT = 0x000F;
    
            private const int GWL_EXSTYLE = -20;
            private const int WS_EX_LAYERED = 0x80000;
            private const int LWA_ALPHA = 0x2;
    
            private enum ShowWindowEnum { Hide = 0, ShowNormal = 1, ShowMinimized = 2, ShowMaximized = 3, Maximize = 3, ShowNormalNoActivate = 4, Show = 5, Minimize = 6, ShowMinNoActivate = 7, ShowNoActivate = 8, Restore = 9, ShowDefault = 10, ForceMinimized = 11 };
    
            private struct RECT
            {
                int left;
                int top;
                int right;
                int bottom;
    
                public int Left
                {
                    get { return this.left; }
                }
    
                public int Top
                {
                    get { return this.top; }
                }
    
                public int Width
                {
                    get { return right - left; }
                }
    
                public int Height
                {
                    get { return bottom - top; }
                }
    
                public static implicit operator Rectangle(RECT rect)
                {
                    return new Rectangle(rect.left, rect.top, rect.Width, rect.Height);
                }
            }
    
            [DllImport("user32")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool ShowWindow(IntPtr hWnd, ShowWindowEnum flags);
    
            [DllImport("user32.dll")]
            private static extern uint SendMessage(IntPtr hWnd, uint msg, uint wParam, uint lParam);
    
            [DllImport("user32")]
            private static extern int GetWindowRect(IntPtr hWnd, ref RECT rect);
    
            [DllImport("user32")]
            private static extern int PrintWindow(IntPtr hWnd, IntPtr dc, uint flags);
    
            [DllImport("user32")]
            private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);
    
            [DllImport("user32")]
            private static extern int GetWindowTextLength(IntPtr hWnd);
    
            [DllImport("user32")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool IsWindowVisible(IntPtr hWnd);
    
            [DllImport("user32")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool IsIconic(IntPtr hWnd);
    
            private delegate bool EnumWindowsCallbackHandler(IntPtr hWnd, IntPtr lParam);
    
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool EnumWindows(EnumWindowsCallbackHandler lpEnumFunc, IntPtr lParam);
    
            [DllImport("user32")]
            private static extern int GetWindowLong(IntPtr hWnd, int index);
    
            [DllImport("user32")]
            private static extern int SetWindowLong(IntPtr hWnd, int index, int dwNewLong);
    
            [DllImport("user32")]
            private static extern int SetLayeredWindowAttributes(IntPtr hWnd, byte crey, byte alpha, int flags);
    
            #region Update for 4th October 2007
    
            [DllImport("user32")]
            private static extern int GetClassName(IntPtr hWnd, StringBuilder name, int maxCount);
    
            [DllImport("user32")]
            private static extern IntPtr GetParent(IntPtr hWnd);
    
            [DllImport("user32")]
            private static extern IntPtr SetParent(IntPtr child, IntPtr newParent);
    
            [DllImport("user32.dll")]
            private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool reDraw);
    
            [DllImport("user32.dll")]
            private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);
    
            [StructLayout(LayoutKind.Sequential)]
            private struct WINDOWINFO
            {
                public uint cbSize;
                public RECT rcWindow;
                public RECT rcClient;
                public WindowStyles dwStyle;
                public ExtendedWindowStyles dwExStyle;
                public uint dwWindowStatus;
                public uint cxWindowBorders;
                public uint cyWindowBorders;
                public ushort atomWindowType;
                public ushort wCreatorVersion;
    
                public static uint GetSize()
                {
                    return (uint)Marshal.SizeOf(typeof(WINDOWINFO));
                }
            }
    
            [Flags]
            private enum WindowStyles : uint
            {
                WS_OVERLAPPED = 0x00000000,
                WS_POPUP = 0x80000000,
                WS_CHILD = 0x40000000,
                WS_MINIMIZE = 0x20000000,
                WS_VISIBLE = 0x10000000,
                WS_DISABLED = 0x08000000,
                WS_CLIPSIBLINGS = 0x04000000,
                WS_CLIPCHILDREN = 0x02000000,
                WS_MAXIMIZE = 0x01000000,
                WS_BORDER = 0x00800000,
                WS_DLGFRAME = 0x00400000,
                WS_VSCROLL = 0x00200000,
                WS_HSCROLL = 0x00100000,
                WS_SYSMENU = 0x00080000,
                WS_THICKFRAME = 0x00040000,
                WS_GROUP = 0x00020000,
                WS_TABSTOP = 0x00010000,
    
                WS_MINIMIZEBOX = 0x00020000,
                WS_MAXIMIZEBOX = 0x00010000,
    
                WS_CAPTION = WS_BORDER | WS_DLGFRAME,
                WS_TILED = WS_OVERLAPPED,
                WS_ICONIC = WS_MINIMIZE,
                WS_SIZEBOX = WS_THICKFRAME,
                WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
    
                WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
                WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
                WS_CHILDWINDOW = WS_CHILD,
            }
    
            #endregion
    
            #region Update for 10October 2007
    
            [Flags]
            private enum ExtendedWindowStyles : uint
            {
                WS_EX_DLGMODALFRAME = 0x00000001,
                WS_EX_NOPARENTNOTIFY = 0x00000004,
                WS_EX_TOPMOST = 0x00000008,
                WS_EX_ACCEPTFILES = 0x00000010,
                WS_EX_TRANSPARENT = 0x00000020,
                WS_EX_MDICHILD = 0x00000040,
                WS_EX_TOOLWINDOW = 0x00000080,
                WS_EX_WINDOWEDGE = 0x00000100,
                WS_EX_CLIENTEDGE = 0x00000200,
                WS_EX_CONTEXTHELP = 0x00000400,
                WS_EX_RIGHT = 0x00001000,
                WS_EX_LEFT = 0x00000000,
                WS_EX_RTLREADING = 0x00002000,
                WS_EX_LTRREADING = 0x00000000,
                WS_EX_LEFTSCROLLBAR = 0x00004000,
                WS_EX_RIGHTSCROLLBAR = 0x00000000,
                WS_EX_CONTROLPARENT = 0x00010000,
                WS_EX_STATICEDGE = 0x00020000,
                WS_EX_APPWINDOW = 0x00040000,
                WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE),
                WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
            }
            #endregion
    
            #endregion
    
            #region Statics
    
            #region Update for 10 Ocrober 2007
    
            private static bool forceMDI = true;
    
            /// <summary>
            /// if is true ,will force the mdi child to be captured completely ,maybe incompatible with some programs
            /// </summary>
            public static bool ForceMDICapturing
            {
                get { return forceMDI; }
                set { forceMDI = value; }
            }
            #endregion
    
            [ThreadStatic]
            private static bool countMinimizedWindows;
    
            [ThreadStatic]
            private static bool useSpecialCapturing;
    
            [ThreadStatic]
            public static WindowSnapCollection windowSnaps;
    
            [ThreadStatic]
            private static int winLong;
    
            [ThreadStatic]
            private static bool minAnimateChanged = false;
    
    
            private static bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam)
            {
                bool specialCapturing = false;
    
                if (hWnd == IntPtr.Zero) return false;
    
                if (!IsWindowVisible(hWnd)) return true;
    
                if (!countMinimizedWindows)
                {
                    if (IsIconic(hWnd)) return true;
                }
                else if (IsIconic(hWnd) && useSpecialCapturing) specialCapturing = true;
    
                if (GetWindowText(hWnd) == PROGRAMMANAGER) return true;
    
                windowSnaps.Add(new WindowSnap(hWnd, specialCapturing));
    
                return true;
            }
    
            /// <summary>
            /// Get the collection of WindowSnap instances fro all available windows
            /// </summary>
            /// <param name="minimized">Capture a window even it's Minimized</param>
            /// <param name="specialCapturring">use special capturing method to capture minmized windows</param>
            /// <returns>return collections of WindowSnap instances</returns>
            public static WindowSnapCollection GetAllWindows(bool minimized, bool specialCapturring)
            {
                windowSnaps = new WindowSnapCollection();
                countMinimizedWindows = minimized;//set minimized flag capture
                useSpecialCapturing = specialCapturring;//set specialcapturing flag
    
                EnumWindowsCallbackHandler callback = new EnumWindowsCallbackHandler(EnumWindowsCallback);
                EnumWindows(callback, IntPtr.Zero);
    
                return new WindowSnapCollection(windowSnaps.ToArray(), true);
            }
    
            /// <summary>
            /// Get the collection of WindowSnap instances fro all available windows
            /// </summary>
            /// <returns>return collections of WindowSnap instances</returns>
            public static WindowSnapCollection GetAllWindows()
            {
                return GetAllWindows(false, false);
            }
    
            /// <summary>
            /// Take a Snap from the specific Window
            /// </summary>
            /// <param name="hWnd">Handle of the Window</param>
            /// <param name="useSpecialCapturing">if you need to capture from the minimized windows set it true,otherwise false</param>
            /// <returns></returns>
            public static WindowSnap GetWindowSnap(IntPtr hWnd, bool useSpecialCapturing)
            {
                if (!useSpecialCapturing)
                    return new WindowSnap(hWnd, false);
                return new WindowSnap(hWnd, NeedSpecialCapturing(hWnd));
            }
    
            private static bool NeedSpecialCapturing(IntPtr hWnd)
            {
                if (IsIconic(hWnd)) return true;
                return false;
            }
    
            private static Bitmap GetWindowImage(IntPtr hWnd, Size size)
            {
                try
                {
                    if (size.IsEmpty || size.Height < 0 || size.Width < 0) return null;
    
                    Bitmap bmp = new Bitmap(size.Width, size.Height);
                    Graphics g = Graphics.FromImage(bmp);
                    IntPtr dc = g.GetHdc();
    
                    PrintWindow(hWnd, dc, 0);
    
                    g.ReleaseHdc();
                    g.Dispose();
    
                    return bmp;
                }
                catch { return null; }
            }
    
            private static string GetWindowText(IntPtr hWnd)
            {
                int length = GetWindowTextLength(hWnd) + 1;
                StringBuilder name = new StringBuilder(length);
    
                GetWindowText(hWnd, name, length);
    
                return name.ToString();
            }
    
            private static Rectangle GetWindowPlacement(IntPtr hWnd)
            {
                RECT rect = new RECT();
    
                GetWindowRect(hWnd, ref rect);
    
                return rect;
            }
    
            private static void EnterSpecialCapturing(IntPtr hWnd)
            {
                if (XPAppearance.MinAnimate)
                {
                    XPAppearance.MinAnimate = false;
                    minAnimateChanged = true;
                }
    
    
                winLong = GetWindowLong(hWnd, GWL_EXSTYLE);
                SetWindowLong(hWnd, GWL_EXSTYLE, winLong | WS_EX_LAYERED);
                SetLayeredWindowAttributes(hWnd, 0, 1, LWA_ALPHA);
    
                ShowWindow(hWnd, ShowWindowEnum.Restore);
    
                SendMessage(hWnd, WM_PAINT, 0, 0);
            }
    
            private static void ExitSpecialCapturing(IntPtr hWnd)
            {
                ShowWindow(hWnd, ShowWindowEnum.Minimize);
                SetWindowLong(hWnd, GWL_EXSTYLE, winLong);
    
                if (minAnimateChanged)
                {
                    XPAppearance.MinAnimate = true;
                    minAnimateChanged = false;
                }
    
            }
    
            #endregion
    
            private Bitmap image;
            private Size size;
            private Point location;
            private string text;
            private IntPtr hWnd;
            private bool isIconic;
    
            /// <summary>
            /// Get the Captured Image of the Window
            /// </summary>
            public Bitmap Image
            {
                get
                {
                    if (this.image != null)
                        return this.image;
                    return null;
                }
            }
            /// <summary>
            /// Get Size of Snapped Window
            /// </summary>
            public Size Size
            {
                get { return this.size; }
            }
            /// <summary>
            /// Get Location of Snapped Window
            /// </summary>
            public Point Location
            {
                get { return this.location; }
            }
            /// <summary>
            /// Get Title of Snapped Window
            /// </summary>
            public string Text
            {
                get { return this.text; }
            }
            /// <summary>
            /// Get Handle of Snapped Window
            /// </summary>
            public IntPtr Handle
            {
                get { return this.hWnd; }
            }
            /// <summary>
            /// if the state of the window is minimized return true otherwise returns false
            /// </summary>
            public bool IsMinimized
            {
                get { return this.isIconic; }
            }
    
            private WindowSnap(IntPtr hWnd, bool specialCapturing)
            {
                this.isIconic = IsIconic(hWnd);
                this.hWnd = hWnd;
    
                if (specialCapturing)
                    EnterSpecialCapturing(hWnd);
    
                #region Child Support (Enter)
    
                WINDOWINFO wInfo = new WINDOWINFO();
                wInfo.cbSize = WINDOWINFO.GetSize();
                GetWindowInfo(hWnd, ref wInfo);
    
                bool isChild = false;
                IntPtr parent = GetParent(hWnd);
                Rectangle pos = new Rectangle();
                Rectangle parentPos = new Rectangle();
    
                if (forceMDI && parent != IntPtr.Zero && (wInfo.dwExStyle & ExtendedWindowStyles.WS_EX_MDICHILD) == ExtendedWindowStyles.WS_EX_MDICHILD
                    //&& (
                    //(wInfo.dwStyle & WindowStyles.WS_CHILDWINDOW) == WindowStyles.WS_CHILDWINDOW||
                    //(wInfo.dwStyle & WindowStyles.WS_CHILD) == WindowStyles.WS_CHILD)
                    )//added 10 october 2007
                    
                {
                    StringBuilder name = new StringBuilder();
                    GetClassName(parent, name, RUNDLL.Length + 1);
                    if (name.ToString() != RUNDLL)
                    {
                        isChild = true;
                        pos = GetWindowPlacement(hWnd);
                        MoveWindow(hWnd, int.MaxValue, int.MaxValue, pos.Width, pos.Height, true);
    
                        SetParent(hWnd, IntPtr.Zero);
    
                        parentPos = GetWindowPlacement(parent);
                    }
                }
                #endregion
    
                Rectangle rect = GetWindowPlacement(hWnd);
    
                this.size = rect.Size;
                this.location = rect.Location;
                this.text = GetWindowText(hWnd);
                this.image = GetWindowImage(hWnd, this.size);
    
                #region Child Support (Exit)
    
                if (isChild)
                {
                    SetParent(hWnd, parent);
    
                    //int x = pos.X - parentPos.X;
                    //int y = pos.Y - parentPos.Y;
    
                    int x = wInfo.rcWindow.Left - parentPos.X;
                    int y = wInfo.rcWindow.Top - parentPos.Y;
    
                    if ((wInfo.dwStyle & WindowStyles.WS_THICKFRAME) == WindowStyles.WS_THICKFRAME)
                    {
                        x -= SystemInformation.Border3DSize.Width;
                        y -= SystemInformation.Border3DSize.Height;
                    }
    
                    MoveWindow(hWnd, x, y, pos.Width, pos.Height, true);
                }
                #endregion
    
                if (specialCapturing)
                    ExitSpecialCapturing(hWnd);
            }
    
            /// <summary>
            /// Gets the Name and Handle of the Snapped Window
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                StringBuilder str = new StringBuilder();
                str.AppendFormat("Window Text: {0}, Handle: {1}", this.text, this.hWnd.ToString());
    
                return str.ToString();
            }
        }
    }
    


    In this class i did one change. The variable windowSnaps i did it public:

    [ThreadStatic]
    public static WindowSnapCollection windowSnaps;

    It was private.

    Then there are two methods one of them i'm calling to start the operation in form1 the GetAllWindows and the second one that update and add items to the windowSbaps:

    private static bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam)
            {
                bool specialCapturing = false;
    
                if (hWnd == IntPtr.Zero) return false;
    
                if (!IsWindowVisible(hWnd)) return true;
    
                if (!countMinimizedWindows)
                {
                    if (IsIconic(hWnd)) return true;
                }
                else if (IsIconic(hWnd) && useSpecialCapturing) specialCapturing = true;
    
                if (GetWindowText(hWnd) == PROGRAMMANAGER) return true;
    
                windowSnaps.Add(new WindowSnap(hWnd, specialCapturing));
    
                return true;
            }
    
            /// <summary>
            /// Get the collection of WindowSnap instances fro all available windows
            /// </summary>
            /// <param name="minimized">Capture a window even it's Minimized</param>
            /// <param name="specialCapturring">use special capturing method to capture minmized windows</param>
            /// <returns>return collections of WindowSnap instances</returns>
            public static WindowSnapCollection GetAllWindows(bool minimized, bool specialCapturring)
            {
                windowSnaps = new WindowSnapCollection();
                countMinimizedWindows = minimized;//set minimized flag capture
                useSpecialCapturing = specialCapturring;//set specialcapturing flag
    
                EnumWindowsCallbackHandler callback = new EnumWindowsCallbackHandler(EnumWindowsCallback);
                EnumWindows(callback, IntPtr.Zero);
    
                return new WindowSnapCollection(windowSnaps.ToArray(), true);
            }

    And last the WindowSnapCollection class code. The variable windowSnaps is type of WindowSnapCollection:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace MinimizeCapture
    {
        class WindowSnapCollection:List<WindowSnap>
        {
            private readonly bool asReadonly = false;
    
            const string READONLYEXCEPTIONTEXT="The Collection is marked as Read-Only and it cannot be modified";
            private void ThrowAReadonlyException()
            {
                throw new Exception(READONLYEXCEPTIONTEXT);
            }
    
            public new void Add(WindowSnap item)
            {
                if (this.asReadonly)this.ThrowAReadonlyException();
                base.Add(item);
            }
    
            public new void AddRange(IEnumerable<WindowSnap> collection)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.AddRange(collection);
            }
    
            public new void Clear()
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Clear();
            }
    
            public new void Insert(int index,WindowSnap item)
            {
                            if (this.asReadonly) this.ThrowAReadonlyException();
                base.Insert(index,item);
            }
    
            public new void InsertRange(int index, IEnumerable<WindowSnap> collection)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.InsertRange(index, collection);
            }
    
            public new void Remove(WindowSnap item)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Remove(item);
            }
    
            public new void RemoveAll(Predicate<WindowSnap> match)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.RemoveAll(match);
            }
    
            public new void RemoveAt(int index)
            {
                            if (this.asReadonly) this.ThrowAReadonlyException();
                base.RemoveAt(index);
            }
    
            public new void RemoveRange(int index,int count)
            {
                            if (this.asReadonly) this.ThrowAReadonlyException();
                base.RemoveRange(index,count);
            }
    
            public new void Reverse(int index, int count)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Reverse(index, count);
            }
    
            public new void Reverse()
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Reverse();
            }
    
            public new void Sort()
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Sort();
            }
    
            public new void Sort(Comparison<WindowSnap> comparison)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Sort(comparison);
            }
    
            public new void Sort(IComparer<WindowSnap> compare)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Sort(compare);
            }
    
            public new void Sort(int index,int count,IComparer<WindowSnap> compare)
            {
                if (this.asReadonly) this.ThrowAReadonlyException();
                base.Sort(index,count,compare);
            }
    
    
            public bool Contains(IntPtr hWnd)
            {
                if (GetWindowSnap(hWnd) != null) return true;
                return false;
                
            }
    
            public WindowSnap GetWindowSnap(IntPtr hWnd)
            {
                checkHWnd = hWnd;
                return base.Find(IshWndPredict);          
            }
    
            public void Update(WindowSnap item)
            {
                lock (this)
                {
                    WindowSnap oldSnap = this.GetWindowSnap(item.Handle);
                    this.Remove(oldSnap);
                    this.Add(item);
                }
            }
    
            public WindowSnapCollection GetAllMinimized()
            {
                WindowSnapCollection wsCol= (WindowSnapCollection) base.FindAll(IsMinimizedPredict);
                return wsCol;
            }
    
            private static bool IsMinimizedPredict(WindowSnap ws)
            {
                if (ws.IsMinimized) return true;
                return false;
            }
    
            [ThreadStatic]private static IntPtr checkHWnd;
            private static bool IshWndPredict(WindowSnap ws)
            {
                if (ws.Handle == checkHWnd)
                    return true;
                return false;
            }
    
            public bool ReadOnly
            {
                get{return this.asReadonly;}
            }
    
            public WindowSnapCollection(WindowSnap[] items, bool asReadOnly)
            {
                base.AddRange(items);
                base.TrimExcess();
                this.asReadonly = asReadOnly;
            }
    
            public WindowSnapCollection()
            {
                this.asReadonly = false;
            }
        }
    }
    

    What i want is in form1 to update label2.text with the number of items that are adding in real time to windowSnaps.

    • Moved by CoolDadTx Sunday, July 9, 2017 10:08 PM Winforms related
    Sunday, July 9, 2017 2:06 AM

Answers

  • Hi Chocolade1972,

    >>Why when using async.task,await it's not working when trying to report progress from another class ?

    I debug your code then I find there are some error grammar when you try to use asynchronously wait, first you can not write the code as below:

    await ProcessObject(WindowSnap.windowSnaps.Count);

    Try to change it as:

    Task task = ProcessObject(WindowSnap.windowSnaps.Count);

    Then please change the code:

            private async void button1_Click(object sender, EventArgs e)
            {
                // almost 15 process
                /*for (int i = 0; i < 100; i++)
                {
                    // call a async method to process
                    await ProcessObject(i);
                }*/
                this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());
                await ProcessObject(WindowSnap.windowSnaps.Count);
            }
    
            private async Task ProcessObject(int process)// <--Note the return type
            {
                // my code is here with some loops
                await Task.Run(() =>
                {
                    //Will be run in ThreadPool thread
                    //Do whatever cpu bound work here
                    //Thread.Sleep(1000);
                });
    
                //At this point code runs in UI thread
                //process.Progress++;
    
                // feedback to UI
                UpdateRow(process);
            }
    
            private void UpdateRow(int process)
            {
                label2.Text = process.ToString();
            }

    To:

            static Task<string> Sleep()
            {
                return Task<string>.Run(() =>
                {
                    Thread.Sleep(1000);
                    return "sleep";
                });
            }
    
            private async Task ProcessObject(int process)// <--Note the return type
            {
                // my code is here with some loops
                //await Task.Run(() =>
                //{
                //    //Will be run in ThreadPool thread
                //    //Do whatever cpu bound work here
                //    Thread.Sleep(1000);
                //});
    
                await Sleep();
    
                //At this point code runs in UI thread
                //process.Progress++;
    
                // feedback to UI
                UpdateRow(process);
            }
    
            private void UpdateRow(int process)
            {
                label2.Text = process.ToString();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                // almost 15 process
                for (int i = 0; i < 100; i++)
                {
                    //call a async method to process
                    Task task1 = ProcessObject(i);
                }
    
                //Task task = ProcessObject(WindowSnap.windowSnaps.Count);
            }

    Hope this helps!

    Best Regards,

    Stanly


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Proposed as answer by Stanly Fan Thursday, July 20, 2017 6:57 AM
    • Marked as answer by Chocolade1972 Friday, July 28, 2017 2:13 PM
    Thursday, July 20, 2017 6:57 AM