Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / July 2007

Tip: Looking for answers? Try searching our database.

unrelated event killing an asynchronous thread in progress

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
James Irvine - 11 Jul 2007 22:29 GMT
I posted this to an ASP.Net group awhile ago, but nobody responded, so
maybe this more in the C# realm.  Anyway, I launch an asynchronous
thread by clicking ButtonInitAsyncThread, which works fine.  When it's
done, it sends back it's results.

But, while this thread is still running, if I click on
ButtonCheckThreadStatus, which has nothing to do with the async thread
running, it cancels the thread, and the thread never sends back the
results.  What causes this?

thanks  -James

The complete C# code-behind:

using System;
using System.Threading;

public partial class testThreads : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    public delegate long SampSyncSqrDelegate(long i);

    protected void ButtonInitAsyncThread_Click(object sender, EventArgs
e)  // async call
    {
        long inParm = Convert.ToInt32(TextBoxInParm.Text);
        long callResult = -1;

        WorkerClass sampSyncObj = new WorkerClass();

        // launch longWindedMethod method Asynchronously:
        SampSyncSqrDelegate sampleDelegate = new
SampSyncSqrDelegate(sampSyncObj.longWindedMethod);

        IAsyncResult aResult = sampleDelegate.BeginInvoke(inParm, null,
null);

        //Wait for the call to complete
        aResult.AsyncWaitHandle.WaitOne();

        // get the output returned back:
        callResult = sampleDelegate.EndInvoke(aResult);
        LabelThreadStatus.Text = Convert.ToString(callResult);
    }

    protected void ButtonCheckThreadStatus_Click(object sender,
EventArgs e)
    {
        Label1.Text = Convert.ToString(DateTime.Now);
    }
}

public class WorkerClass
{
    // A method that does some time-consuming work - returns the number
passed in + 'a':
    public long longWindedMethod(long longIn)
    {
        int a = 0;

        while (a < 5)
        {
            System.Threading.Thread.Sleep(1000);
            System.Console.WriteLine(a);
            a++;
        }
        return a + longIn;
    }
}

And the complete aspx listing:

<%@ Page Language="C#" MasterPageFile="~/MasterPageGold.master"
AutoEventWireup="true" CodeFile="why.aspx.cs" Inherits="testThreads"
Title="Untitled Page" %>
<asp:Content ID="Content1"
ContentPlaceHolderID="ContentPlaceHolderForBody" Runat="Server">
    <br />
    <asp:Button ID="ButtonInitAsyncThread" runat="server" Text="init
async thread" OnClick="ButtonInitAsyncThread_Click"  />&nbsp;
    <asp:TextBox ID="TextBoxInParm" runat="server">78</asp:TextBox>
    <asp:Label ID="LabelThreadStatus" runat="server" Text="thread
status"></asp:Label><br />
    <br />
    <br />
    <asp:Button ID="ButtonCheckThreadStatus" runat="server"
Text="CheckThreadStatus" OnClick="ButtonCheckThreadStatus_Click" />
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</asp:Content>
Peter Duniho - 11 Jul 2007 22:56 GMT
> I posted this to an ASP.Net group awhile ago, but nobody responded, so  
> maybe this more in the C# realm.  Anyway, I launch an asynchronous  
[quoted text clipped - 5 lines]
> running, it cancels the thread, and the thread never sends back the  
> results.  What causes this?

Actually, I think this may well have at least a little to do with it being  
ASP.NET versus C#.

In a plain Form application, doing what you're doing here would result in  
an inoperable UI.  Because you wait in the click handler until the long  
process is done, nothing else in the form can be handled.  The user  
wouldn't be able to click on the status button in the first place, nor do  
anything else with the UI.

So presumably, at least some aspect of the problem is due to the web-based  
environment in which your code is operating.

What exactly is going on, I can't say.  I don't know anything about  
ASP.NET.  You should verify what exactly is happening though.  It seems  
odd to me that clicking on a button in the browser (I assume that's where  
the UI is shown) would cause the thread in your click handler to be  
aborted.  So the first thing to do is put in some logging or something so  
that you can tell whether the thread really has stopped, or if it's just  
somehow been disconnected from the UI.

I suspect it's the latter, but what the solution for that might be I don't  
know.

What I can tell you is that it doesn't make much sense to me for code to  
start a new thread to run some processing, and then to simply sit and wait  
for that thread to finish.  The processing might as well just be done on  
the same thread if you're going to do that.

Pete
James Irvine - 11 Jul 2007 23:35 GMT
>> I posted this to an ASP.Net group awhile ago, but nobody responded, so
>> maybe this more in the C# realm.  Anyway, I launch an asynchronous
[quoted text clipped - 35 lines]
>
> Pete

I rewrote it as a Forms app, and my error became clear.  Thanks for pointing out the defect!  -James

This does what I was aiming for (moving the results harvesting to another event fixed it).  Now while the background
thread is running I can click away on other buttons:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplicationAsyncButtons
{
    public partial class Form1 : Form
    {
        // Async delegate used to call a method with this signature asynchronously
        public delegate long SampSyncSqrDelegate(long i);
        public IAsyncResult aResult;
        public SampSyncSqrDelegate sampleDelegate;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            long inParm = Convert.ToInt32(TextBoxInParm.Text);

            WorkerClass sampSyncObj = new WorkerClass();

            // launch longWindedMethod method Asynchronously:
            sampleDelegate = new SampSyncSqrDelegate(sampSyncObj.longWindedMethod);

            aResult = sampleDelegate.BeginInvoke(inParm, null, null);

            // *** Don't ***  wait here for the call to complete
            //aResult.AsyncWaitHandle.WaitOne();

            // get the output returned back:
            //callResult = sampleDelegate.EndInvoke(aResult);
            //LabelThreadStatus.Text = Convert.ToString(callResult);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            label2.Text = Convert.ToString(DateTime.Now);
        }

        private void buttonGetResults_Click(object sender, EventArgs e)
        {
            long callResult = -1;

            // get the output returned back:
            callResult = sampleDelegate.EndInvoke(aResult);
            LabelThreadStatus.Text = Convert.ToString(callResult);
        }

    }

    public class WorkerClass
    {
        // A method that does some time-consuming work - returns the number passed in + 'a':
        public long longWindedMethod(long longIn)
        {
            int a = 0;

            while (a < 5)
            {
                System.Threading.Thread.Sleep(1000);
                System.Console.WriteLine(a);
                a++;
            }
            return a + longIn;
        }
    }

}
Peter Duniho - 12 Jul 2007 00:09 GMT
> I rewrote it as a Forms app, and my error became clear.  Thanks for  
> pointing out the defect!  -James
>
> This does what I was aiming for (moving the results harvesting to  
> another event fixed it).  Now while the background thread is running I  
> can click away on other buttons:

Hmmm...I think you're almost there.  :)

In particular, I'm pretty sure that calling EndInvoke() on the delegate  
will block until the delegate has returned.  This means you've simply  
moved the blocking behavior from the click handler for the start button to  
the click handler for the "get results" button.  If you click that button  
before the delegate is done, you have the same problem.

Better would be to use a callback or event for the long process delegate  
to use, so that you are notified when it finishes, rather than relying on  
the user to not get the results until after it's done.

Pete
James Irvine - 12 Jul 2007 01:31 GMT
>> I rewrote it as a Forms app, and my error became clear.  Thanks for
>> pointing out the defect!  -James
[quoted text clipped - 16 lines]
>
> Pete

Way better.  In fact, awesome!  thanks for the lesson  -James

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplicationAsyncButtons
{
    public partial class Form1 : Form
    {
        // Async delegate used to call a method with this signature asynchronously
        public delegate long SampSyncSqrDelegate(long i);
        public IAsyncResult aResult;
        public SampSyncSqrDelegate sampleDelegate;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            long inParm = Convert.ToInt32(TextBoxInParm.Text);

            WorkerClass sampSyncObj = new WorkerClass();

            // launch longWindedMethod method Asynchronously:
            sampleDelegate = new SampSyncSqrDelegate(sampSyncObj.longWindedMethod);

            aResult = sampleDelegate.BeginInvoke(inParm, OnAsyncCallBack, null);
            //del.BeginInvoke(az, bz, OnAsyncCallBack, null);

            //Wait for the call to complete
            //aResult.AsyncWaitHandle.WaitOne();

            // get the output returned back:
            //callResult = sampleDelegate.EndInvoke(aResult);
            //LabelThreadStatus.Text = Convert.ToString(callResult);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            label2.Text = Convert.ToString(DateTime.Now);
        }

        void OnAsyncCallBack(IAsyncResult asyncResult) //  goes here on callback
        {
            // get the output returned back:
            long callResult = sampleDelegate.EndInvoke(aResult);
            LabelThreadStatus.Text = Convert.ToString(callResult);
        }

    }

    public class WorkerClass
    {
        // A method that does some time-consuming work - returns the number passed in + 'a':
        public long longWindedMethod(long longIn)
        {
            int a = 0;

            while (a < 5)
            {
                System.Threading.Thread.Sleep(1000);
                System.Console.WriteLine(a);
                a++;
            }
            return a + longIn;
        }
    }

}
James Irvine - 21 Jul 2007 01:00 GMT
>> I posted this to an ASP.Net group awhile ago, but nobody responded, so
>> maybe this more in the C# realm.  Anyway, I launch an asynchronous
[quoted text clipped - 23 lines]
> where the UI is shown) would cause the thread in your click handler to
> be aborted.  

.......
> So the first thing to do is put in some logging or
> something so that you can tell whether the thread really has stopped, or
> if it's just somehow been disconnected from the UI.

Just out of curiosity, I put in some file writing code and a sleeper in the background thread, ran the webpage, and then closed the page before the background
thread had finished, just to see if it would continue writing files even after it's head was cut off.  It does.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.