> 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.