[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

David

10/29/2008 4:39:00 PM

Hi all,

I am currently writing an app for a mobile phone. (WM6) with Compact
Framework, though this probably has no bearing on my question.

I am building the app as a layered app. I have my main screen, but behind
this, I have for example, a class that talks to the bluetooth device.

So, for example...

Form1.cs

Here I have...

Bluetooth bt = new Bluetooth();
bt.Connect(); // Asks the bluetooth connection to start and be ready to
handle incoming files.


classes\Bluetooth.cs

public void Connect()
{
// Do my bluetooth actions.
// This also starts a thread.
}

private void BTThreadHandler()
{
// This is the thread handler that was started in connect.
// This saves a file.
}

What I need to do is to allow the BTThreadHandler to notify Form1.cs when a
file has arrived. I actually need to pass the filename. I could store the
filename in a property but if another file comes in, the property will no
doubt change, so a property is not really safe in this instance.


For the event handler, in the past, I have done something like this, but I
don't know if this would be normal... is it?

Form1.cs
bt.EventUpdateData += new EventHandler(CollectDataHandler);

private void CollectDataHandler(object sender, EventArgs e)
{
// handle the event
}


classes\Bluetooth.cs

public event EventHandler EventUpdateData;

private void BTThreadHandler()
{
// This is the thread handler that was started in connect.
// This saves a file.

// Create an event
if (EventUpdateData != null)
EventUpdateData(sender, e); // Note, this is copied, so
sender and e are not valid here.
}


Is this how it is done?

I guess that to pass the filename string, instead of using sender and e, I
just send the string.


Your advice is appreciated. If the above is the wrong way, I would
appreciate the details of how it should be done.

--
Best regards,
Dave Colliver.
http://www.Ashfiel...
~~
http://www.FOCUSP... - Local franchises available


9 Answers

sloan

10/29/2008 4:51:00 PM

0

I think the step you're missing is that you can create your own EventArgs
and add any data you want.

Then you can define your own delegate


public delegate void SomethingHappenedWithARootFolder (object sender,
RootFolderEventArgs arg);




public class RootFolderEventArgs : System.EventArgs
{
private Guid _rootFolderUUID = Guid.Employ;
private string _folderPath = string.Empty;
public string FolderPath
{
get
{
return _folderPath;
}
set
{
_folderPath = value;
}
}

public Guid RootFolderUUID
{
get
{
return _rootFolderUUID;
}
set
{
_rootFolderUUID = value;
}
}

}


======================================
Then on some class, you expose the event


public MyClass
{


public event SomethingHappenedWithARootFolder
SomethingHappenedWithARootFolderEvent;


private void OnRootFolderEventArgs (object sender, RootFolderEventArgs arg)

{

if (null != SomethingHappenedWithARootFolderEvent)

{

SomethingHappenedWithARootFolderEvent(sender, arg);

}

}



public void SomeNormalCode()

{

RootFolderEventArgs args = new RootFolderEventArgs ();

args.RootFolderUUID= Guid.Empty;

args.FolderPath= "c:\wutemp\";

OnRootFolderEventArgs (this, args );



}


}



This may not be the latest/greatest SYNTAX or usage, but it'll get you
going.






The

"David" <david.colliver.NEWS@revilloc.REMOVETHIS.com> wrote in message
news:OX1LqTeOJHA.1012@TK2MSFTNGP04.phx.gbl...
> Hi all,
>
> I am currently writing an app for a mobile phone. (WM6) with Compact
> Framework, though this probably has no bearing on my question.
>
> I am building the app as a layered app. I have my main screen, but behind
> this, I have for example, a class that talks to the bluetooth device.
>
> So, for example...
>
> Form1.cs
>
> Here I have...
>
> Bluetooth bt = new Bluetooth();
> bt.Connect(); // Asks the bluetooth connection to start and be ready to
> handle incoming files.
>
>
> classes\Bluetooth.cs
>
> public void Connect()
> {
> // Do my bluetooth actions.
> // This also starts a thread.
> }
>
> private void BTThreadHandler()
> {
> // This is the thread handler that was started in connect.
> // This saves a file.
> }
>
> What I need to do is to allow the BTThreadHandler to notify Form1.cs when
> a file has arrived. I actually need to pass the filename. I could store
> the filename in a property but if another file comes in, the property will
> no doubt change, so a property is not really safe in this instance.
>
>
> For the event handler, in the past, I have done something like this, but I
> don't know if this would be normal... is it?
>
> Form1.cs
> bt.EventUpdateData += new EventHandler(CollectDataHandler);
>
> private void CollectDataHandler(object sender, EventArgs e)
> {
> // handle the event
> }
>
>
> classes\Bluetooth.cs
>
> public event EventHandler EventUpdateData;
>
> private void BTThreadHandler()
> {
> // This is the thread handler that was started in connect.
> // This saves a file.
>
> // Create an event
> if (EventUpdateData != null)
> EventUpdateData(sender, e); // Note, this is copied, so
> sender and e are not valid here.
> }
>
>
> Is this how it is done?
>
> I guess that to pass the filename string, instead of using sender and e, I
> just send the string.
>
>
> Your advice is appreciated. If the above is the wrong way, I would
> appreciate the details of how it should be done.
>
> --
> Best regards,
> Dave Colliver.
> http://www.Ashfiel...
> ~~
> http://www.FOCUSP... - Local franchises available
>


David

10/29/2008 5:01:00 PM

0

Thanks, so in my own example, it is the bluetooth.cs that needs to raise the
event... and it is the form1.cs that needs to handle it.

Where would the delegate go?

your MyClass I am assuming is the same as my form1.cs

I am also assuming that your SomeNormalCode() is what should be in my
bluetooth.cs

--
Best regards,
Dave Colliver.
http://www.Ashfiel...
~~
http://www.FOCUSP... - Local franchises available


"sloan" <sloan@ipass.net> wrote in message
news:OSf8sZeOJHA.144@TK2MSFTNGP03.phx.gbl...
>I think the step you're missing is that you can create your own EventArgs
>and add any data you want.
>
> Then you can define your own delegate
>
>
> public delegate void SomethingHappenedWithARootFolder (object sender,
> RootFolderEventArgs arg);
>
>
>
>
> public class RootFolderEventArgs : System.EventArgs
> {
> private Guid _rootFolderUUID = Guid.Employ;
> private string _folderPath = string.Empty;
> public string FolderPath
> {
> get
> {
> return _folderPath;
> }
> set
> {
> _folderPath = value;
> }
> }
>
> public Guid RootFolderUUID
> {
> get
> {
> return _rootFolderUUID;
> }
> set
> {
> _rootFolderUUID = value;
> }
> }
>
> }
>
>
> ======================================
> Then on some class, you expose the event
>
>
> public MyClass
> {
>
>
> public event SomethingHappenedWithARootFolder
> SomethingHappenedWithARootFolderEvent;
>
>
> private void OnRootFolderEventArgs (object sender, RootFolderEventArgs
> arg)
>
> {
>
> if (null != SomethingHappenedWithARootFolderEvent)
>
> {
>
> SomethingHappenedWithARootFolderEvent(sender, arg);
>
> }
>
> }
>
>
>
> public void SomeNormalCode()
>
> {
>
> RootFolderEventArgs args = new RootFolderEventArgs ();
>
> args.RootFolderUUID= Guid.Empty;
>
> args.FolderPath= "c:\wutemp\";
>
> OnRootFolderEventArgs (this, args );
>
>
>
> }
>
>
> }
>
>
>
> This may not be the latest/greatest SYNTAX or usage, but it'll get you
> going.
>
>
>
>
>
>
> The
>
> "David" <david.colliver.NEWS@revilloc.REMOVETHIS.com> wrote in message
> news:OX1LqTeOJHA.1012@TK2MSFTNGP04.phx.gbl...
>> Hi all,
>>
>> I am currently writing an app for a mobile phone. (WM6) with Compact
>> Framework, though this probably has no bearing on my question.
>>
>> I am building the app as a layered app. I have my main screen, but behind
>> this, I have for example, a class that talks to the bluetooth device.
>>
>> So, for example...
>>
>> Form1.cs
>>
>> Here I have...
>>
>> Bluetooth bt = new Bluetooth();
>> bt.Connect(); // Asks the bluetooth connection to start and be ready
>> to handle incoming files.
>>
>>
>> classes\Bluetooth.cs
>>
>> public void Connect()
>> {
>> // Do my bluetooth actions.
>> // This also starts a thread.
>> }
>>
>> private void BTThreadHandler()
>> {
>> // This is the thread handler that was started in connect.
>> // This saves a file.
>> }
>>
>> What I need to do is to allow the BTThreadHandler to notify Form1.cs when
>> a file has arrived. I actually need to pass the filename. I could store
>> the filename in a property but if another file comes in, the property
>> will no doubt change, so a property is not really safe in this instance.
>>
>>
>> For the event handler, in the past, I have done something like this, but
>> I don't know if this would be normal... is it?
>>
>> Form1.cs
>> bt.EventUpdateData += new EventHandler(CollectDataHandler);
>>
>> private void CollectDataHandler(object sender, EventArgs e)
>> {
>> // handle the event
>> }
>>
>>
>> classes\Bluetooth.cs
>>
>> public event EventHandler EventUpdateData;
>>
>> private void BTThreadHandler()
>> {
>> // This is the thread handler that was started in connect.
>> // This saves a file.
>>
>> // Create an event
>> if (EventUpdateData != null)
>> EventUpdateData(sender, e); // Note, this is copied, so
>> sender and e are not valid here.
>> }
>>
>>
>> Is this how it is done?
>>
>> I guess that to pass the filename string, instead of using sender and e,
>> I just send the string.
>>
>>
>> Your advice is appreciated. If the above is the wrong way, I would
>> appreciate the details of how it should be done.
>>
>> --
>> Best regards,
>> Dave Colliver.
>> http://www.Ashfiel...
>> ~~
>> http://www.FOCUSP... - Local franchises available
>>
>
>


Peter Duniho

10/29/2008 5:44:00 PM

0

On Wed, 29 Oct 2008 10:00:49 -0700, David
<david.colliver.NEWS@revilloc.removethis.com> wrote:

> Thanks, so in my own example, it is the bluetooth.cs that needs to raise
> the
> event... and it is the form1.cs that needs to handle it.
>
> Where would the delegate go?

Actually, you don't need to declare a delegate type anymore. You do need
to still declare your EventArgs sub-class, and that should go in the same
assembly with the Bluetooth class. For the delegate type, you can use the
generic EventHandler<T> class, where the type parameter is your own
EventArgs sub-class.

> your MyClass I am assuming is the same as my form1.cs

In his code sample, it appears to me that MyClass is equivalent to your
Bluetooth class. That is, it's the class that raises the event, not the
one that consumes it.
>
> I am also assuming that your SomeNormalCode() is what should be in my
> bluetooth.cs

For his example, I believe that is correct.

One note: the posted code for raising an event, both yours and sloan's, is
appropriate for single-threaded scenarios, but not multi-threaded.
Sloan's is better in that there is a dedicated event-raising method, but
even his has a threading bug in it. A correct method would look like this:

private void OnRootFolderEventArgs(RootFolderEventArgs arg)
{
EventHandler<RootFolderEventArgs> handler =
SomethingHappenedWithARootFolderEvent;

if (handler != null)
{
handler(this, arg);
}
}

By copying the delegate value before checking it for null, you ensure that
the value can't change from non-null to null between the time you look at
it and the time you try to use it.

Note also that I've removed the "sender" argument to the method. This
should be an instance method, and the sender should always be "this", so
there's no need to pass it as an argument.

One other note: in this example, the EventArgs sub-class itself is being
passed, but it would actually be very reasonable to have the caller simply
pass whatever data goes into the sub-class and then have this method
actually create the sub-class instance. This is especially true if the
sub-class only has a small number of data elements in it (for example,
there's just a single string).

Pete

sloan

10/29/2008 6:14:00 PM

0

// private void OnRootFolderEventArgs(RootFolderEventArgs arg)//
Good point, I (now) see the unneeded (double use of ~this~) in my code.
Aka, the above method doesn't need the first argument of sender.


//> EventHandler<RootFolderEventArgs> handler =
> SomethingHappenedWithARootFolderEvent;//
//Actually, you don't need to declare a delegate type anymore.//

Correct. This was some leftover 1.1 code that got upconverted to 2.0 (in my
original).

.......

I think the guy is on the right path now.




"Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message
news:op.ujsrit0c8jd0ej@petes-computer.local...
> On Wed, 29 Oct 2008 10:00:49 -0700, David
> <david.colliver.NEWS@revilloc.removethis.com> wrote:
>
>> Thanks, so in my own example, it is the bluetooth.cs that needs to raise
>> the
>> event... and it is the form1.cs that needs to handle it.
>>
>> Where would the delegate go?
>
> Actually, you don't need to declare a delegate type anymore. You do need
> to still declare your EventArgs sub-class, and that should go in the same
> assembly with the Bluetooth class. For the delegate type, you can use the
> generic EventHandler<T> class, where the type parameter is your own
> EventArgs sub-class.
>
>> your MyClass I am assuming is the same as my form1.cs
>
> In his code sample, it appears to me that MyClass is equivalent to your
> Bluetooth class. That is, it's the class that raises the event, not the
> one that consumes it.
>>
>> I am also assuming that your SomeNormalCode() is what should be in my
>> bluetooth.cs
>
> For his example, I believe that is correct.
>
> One note: the posted code for raising an event, both yours and sloan's, is
> appropriate for single-threaded scenarios, but not multi-threaded.
> Sloan's is better in that there is a dedicated event-raising method, but
> even his has a threading bug in it. A correct method would look like
> this:
>
> private void OnRootFolderEventArgs(RootFolderEventArgs arg)
> {
> EventHandler<RootFolderEventArgs> handler =
> SomethingHappenedWithARootFolderEvent;
>
> if (handler != null)
> {
> handler(this, arg);
> }
> }
>
> By copying the delegate value before checking it for null, you ensure that
> the value can't change from non-null to null between the time you look at
> it and the time you try to use it.
>
> Note also that I've removed the "sender" argument to the method. This
> should be an instance method, and the sender should always be "this", so
> there's no need to pass it as an argument.
>
> One other note: in this example, the EventArgs sub-class itself is being
> passed, but it would actually be very reasonable to have the caller simply
> pass whatever data goes into the sub-class and then have this method
> actually create the sub-class instance. This is especially true if the
> sub-class only has a small number of data elements in it (for example,
> there's just a single string).
>
> Pete


David

10/29/2008 6:22:00 PM

0

Cool...

I was just coming back to the group after I had tried to implement it (and
failed).

In my form1.cs I have...

bt.FileReceivedEvent += new EventHandler(BTFileReceived);

which points to...

protected void BTFileReceived(object sender, FileReceivedEventArgs e)

{

ReturnPicture.Image = new Bitmap(wsc.SendFile());

}

however, I got a
No overload for 'BTFileReceived' matches delegate 'System.EventHandler'

So, I will try with the extended example posted here.

Thanks for the help and especially showing me the difference between a
single threaded version and a multithreaded version. As the event is being
raised in a thread, it is of particular importance, which is the main reason
I asked. :-)
--
Best regards,
Dave Colliver.
http://www.Ashfiel...
~~
http://www.FOCUSP... - Local franchises available


"sloan" <sloan@ipass.net> wrote in message
news:ebP7EIfOJHA.2060@TK2MSFTNGP02.phx.gbl...
> // private void OnRootFolderEventArgs(RootFolderEventArgs arg)//
> Good point, I (now) see the unneeded (double use of ~this~) in my code.
> Aka, the above method doesn't need the first argument of sender.
>
>
> //> EventHandler<RootFolderEventArgs> handler =
>> SomethingHappenedWithARootFolderEvent;//
> //Actually, you don't need to declare a delegate type anymore.//
>
> Correct. This was some leftover 1.1 code that got upconverted to 2.0 (in
> my original).
>
> ......
>
> I think the guy is on the right path now.
>
>
>
>
> "Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message
> news:op.ujsrit0c8jd0ej@petes-computer.local...
>> On Wed, 29 Oct 2008 10:00:49 -0700, David
>> <david.colliver.NEWS@revilloc.removethis.com> wrote:
>>
>>> Thanks, so in my own example, it is the bluetooth.cs that needs to raise
>>> the
>>> event... and it is the form1.cs that needs to handle it.
>>>
>>> Where would the delegate go?
>>
>> Actually, you don't need to declare a delegate type anymore. You do need
>> to still declare your EventArgs sub-class, and that should go in the same
>> assembly with the Bluetooth class. For the delegate type, you can use
>> the generic EventHandler<T> class, where the type parameter is your own
>> EventArgs sub-class.
>>
>>> your MyClass I am assuming is the same as my form1.cs
>>
>> In his code sample, it appears to me that MyClass is equivalent to your
>> Bluetooth class. That is, it's the class that raises the event, not the
>> one that consumes it.
>>>
>>> I am also assuming that your SomeNormalCode() is what should be in my
>>> bluetooth.cs
>>
>> For his example, I believe that is correct.
>>
>> One note: the posted code for raising an event, both yours and sloan's,
>> is appropriate for single-threaded scenarios, but not multi-threaded.
>> Sloan's is better in that there is a dedicated event-raising method, but
>> even his has a threading bug in it. A correct method would look like
>> this:
>>
>> private void OnRootFolderEventArgs(RootFolderEventArgs arg)
>> {
>> EventHandler<RootFolderEventArgs> handler =
>> SomethingHappenedWithARootFolderEvent;
>>
>> if (handler != null)
>> {
>> handler(this, arg);
>> }
>> }
>>
>> By copying the delegate value before checking it for null, you ensure
>> that the value can't change from non-null to null between the time you
>> look at it and the time you try to use it.
>>
>> Note also that I've removed the "sender" argument to the method. This
>> should be an instance method, and the sender should always be "this", so
>> there's no need to pass it as an argument.
>>
>> One other note: in this example, the EventArgs sub-class itself is being
>> passed, but it would actually be very reasonable to have the caller
>> simply pass whatever data goes into the sub-class and then have this
>> method actually create the sub-class instance. This is especially true
>> if the sub-class only has a small number of data elements in it (for
>> example, there's just a single string).
>>
>> Pete
>
>


sloan

10/29/2008 6:29:00 PM

0


I think your class ( doing the event raising ) needs something like


public event EventHandler<FileReceivedEventArgs > FileReceivedEvent ;



Or do you have it that already?






"David" <david.colliver.NEWS@revilloc.REMOVETHIS.com> wrote in message
news:uJRJSNfOJHA.4876@TK2MSFTNGP05.phx.gbl...
> Cool...
>
> I was just coming back to the group after I had tried to implement it (and
> failed).
>
> In my form1.cs I have...
>
> bt.FileReceivedEvent += new EventHandler(BTFileReceived);
>
> which points to...
>
> protected void BTFileReceived(object sender, FileReceivedEventArgs e)
>
> {
>
> ReturnPicture.Image = new Bitmap(wsc.SendFile());
>
> }
>
> however, I got a
> No overload for 'BTFileReceived' matches delegate 'System.EventHandler'
>
> So, I will try with the extended example posted here.
>
> Thanks for the help and especially showing me the difference between a
> single threaded version and a multithreaded version. As the event is being
> raised in a thread, it is of particular importance, which is the main
> reason I asked. :-)
> --
> Best regards,
> Dave Colliver.
> http://www.Ashfiel...
> ~~
> http://www.FOCUSP... - Local franchises available
>
>
> "sloan" <sloan@ipass.net> wrote in message
> news:ebP7EIfOJHA.2060@TK2MSFTNGP02.phx.gbl...
>> // private void OnRootFolderEventArgs(RootFolderEventArgs arg)//
>> Good point, I (now) see the unneeded (double use of ~this~) in my code.
>> Aka, the above method doesn't need the first argument of sender.
>>
>>
>> //> EventHandler<RootFolderEventArgs> handler =
>>> SomethingHappenedWithARootFolderEvent;//
>> //Actually, you don't need to declare a delegate type anymore.//
>>
>> Correct. This was some leftover 1.1 code that got upconverted to 2.0 (in
>> my original).
>>
>> ......
>>
>> I think the guy is on the right path now.
>>
>>
>>
>>
>> "Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message
>> news:op.ujsrit0c8jd0ej@petes-computer.local...
>>> On Wed, 29 Oct 2008 10:00:49 -0700, David
>>> <david.colliver.NEWS@revilloc.removethis.com> wrote:
>>>
>>>> Thanks, so in my own example, it is the bluetooth.cs that needs to
>>>> raise the
>>>> event... and it is the form1.cs that needs to handle it.
>>>>
>>>> Where would the delegate go?
>>>
>>> Actually, you don't need to declare a delegate type anymore. You do
>>> need to still declare your EventArgs sub-class, and that should go in
>>> the same assembly with the Bluetooth class. For the delegate type, you
>>> can use the generic EventHandler<T> class, where the type parameter is
>>> your own EventArgs sub-class.
>>>
>>>> your MyClass I am assuming is the same as my form1.cs
>>>
>>> In his code sample, it appears to me that MyClass is equivalent to your
>>> Bluetooth class. That is, it's the class that raises the event, not the
>>> one that consumes it.
>>>>
>>>> I am also assuming that your SomeNormalCode() is what should be in my
>>>> bluetooth.cs
>>>
>>> For his example, I believe that is correct.
>>>
>>> One note: the posted code for raising an event, both yours and sloan's,
>>> is appropriate for single-threaded scenarios, but not multi-threaded.
>>> Sloan's is better in that there is a dedicated event-raising method, but
>>> even his has a threading bug in it. A correct method would look like
>>> this:
>>>
>>> private void OnRootFolderEventArgs(RootFolderEventArgs arg)
>>> {
>>> EventHandler<RootFolderEventArgs> handler =
>>> SomethingHappenedWithARootFolderEvent;
>>>
>>> if (handler != null)
>>> {
>>> handler(this, arg);
>>> }
>>> }
>>>
>>> By copying the delegate value before checking it for null, you ensure
>>> that the value can't change from non-null to null between the time you
>>> look at it and the time you try to use it.
>>>
>>> Note also that I've removed the "sender" argument to the method. This
>>> should be an instance method, and the sender should always be "this", so
>>> there's no need to pass it as an argument.
>>>
>>> One other note: in this example, the EventArgs sub-class itself is being
>>> passed, but it would actually be very reasonable to have the caller
>>> simply pass whatever data goes into the sub-class and then have this
>>> method actually create the sub-class instance. This is especially true
>>> if the sub-class only has a small number of data elements in it (for
>>> example, there's just a single string).
>>>
>>> Pete
>>
>>
>
>


Peter Duniho

10/29/2008 6:43:00 PM

0

On Wed, 29 Oct 2008 11:21:36 -0700, David
<david.colliver.NEWS@revilloc.removethis.com> wrote:

> Cool...
>
> I was just coming back to the group after I had tried to implement it
> (and
> failed).
>
> In my form1.cs I have...
>
> bt.FileReceivedEvent += new EventHandler(BTFileReceived);
>
> [...]

In addition to sloan's comment suggesting something you should
double-check, the above can be changed to:

bt.FileReceivedEvent += BTFileReceived;

This does two things. First, it avoids the incorrect construction of an
EventHandler instance. Even if you have the event type correct, you can't
make an EventHandler delegate from a method that doesn't have Object or
EventHandler as the second argument.

The second thing it does is use the newer inferred delegate syntax, where
the compiler looks at the destination type and automatically creates a
delegate of the correct type for you. You could fix the line by changing
"EventHandler" to "EventHandler<FileReceivedEventArgs>", but the newer
syntax is a lot nicer IMHO.

Once you've ensured that the event is declared correctly and changed the
above line, it should compile.

Finally, I'll point out that the .NET convention is for event names to not
include the word "Event" at the end. It's not mandatory by any means, but
following the .NET convention, your event would be named "FileReceived"
instead.

Pete

David

10/29/2008 6:52:00 PM

0

Getting a LOT closer now, thanks for your help so far...

I have just changed my code with this, now my code in my bluetooth file
looks like...

public class FileReceivedEventArgs : System.EventArgs
{
private string _FileName = string.Empty;
public string FileName
{
get { return _FileName; }
set { _FileName = value; }
}
}

class Bluetooth
{
public event EventHandler<FileReceivedEventArgs> FileReceivedEvent;

private btFile()
{
string filename = "test.txt";

// Raise event...
FileReceivedEventArgs args = new FileReceivedEventArgs();
args.FileName = filename;

OnFileReceivedEventArgs(args);
}

private void OnFileReceivedEventArgs(FileReceivedEventArgs args)
{
EventHandler<FileReceivedEventArgs> handler = FileReceived;
if (handler != null)
{
handler(this, args);
}
}
}


but I am still getting an error on my form1 in the same place...

bt.FileReceivedEvent += new EventHandler(BTFileReceived);

(The above line is in my form_load).

The BTFileReceived now looks like...
protected void BTFileReceived(object sender, FileReceivedEventArgs
e)
{
ReturnPicture.Image = new Bitmap(wsc.SendFile());
}



Finally, as this is working via a thread, I am currently declaring wsc at
the class level rather than inside the BTFileReceived. I have just moved my
wsc declaration into the BTFileReceived. Is this required for thread safety?
I am guessing it is, as BTFileReceived will create an instance of the wsc
class for its own use.


--
Best regards,
Dave Colliver.
http://www.Ashfiel...
~~
http://www.FOCUSP... - Local franchises available
"sloan" <sloan@ipass.net> wrote in message
news:uuPbDQfOJHA.4180@TK2MSFTNGP05.phx.gbl...
>
> I think your class ( doing the event raising ) needs something like
>
>
> public event EventHandler<FileReceivedEventArgs > FileReceivedEvent ;
>
>
>
> Or do you have it that already?
>
>
>
>
>
>
> "David" <david.colliver.NEWS@revilloc.REMOVETHIS.com> wrote in message
> news:uJRJSNfOJHA.4876@TK2MSFTNGP05.phx.gbl...
>> Cool...
>>
>> I was just coming back to the group after I had tried to implement it
>> (and failed).
>>
>> In my form1.cs I have...
>>
>> bt.FileReceivedEvent += new EventHandler(BTFileReceived);
>>
>> which points to...
>>
>> protected void BTFileReceived(object sender, FileReceivedEventArgs e)
>>
>> {
>>
>> ReturnPicture.Image = new Bitmap(wsc.SendFile());
>>
>> }
>>
>> however, I got a
>> No overload for 'BTFileReceived' matches delegate 'System.EventHandler'
>>
>> So, I will try with the extended example posted here.
>>
>> Thanks for the help and especially showing me the difference between a
>> single threaded version and a multithreaded version. As the event is
>> being raised in a thread, it is of particular importance, which is the
>> main reason I asked. :-)
>> --
>> Best regards,
>> Dave Colliver.
>> http://www.Ashfiel...
>> ~~
>> http://www.FOCUSP... - Local franchises available
>>
>>
>> "sloan" <sloan@ipass.net> wrote in message
>> news:ebP7EIfOJHA.2060@TK2MSFTNGP02.phx.gbl...
>>> // private void OnRootFolderEventArgs(RootFolderEventArgs arg)//
>>> Good point, I (now) see the unneeded (double use of ~this~) in my code.
>>> Aka, the above method doesn't need the first argument of sender.
>>>
>>>
>>> //> EventHandler<RootFolderEventArgs> handler =
>>>> SomethingHappenedWithARootFolderEvent;//
>>> //Actually, you don't need to declare a delegate type anymore.//
>>>
>>> Correct. This was some leftover 1.1 code that got upconverted to 2.0
>>> (in my original).
>>>
>>> ......
>>>
>>> I think the guy is on the right path now.
>>>
>>>
>>>
>>>
>>> "Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message
>>> news:op.ujsrit0c8jd0ej@petes-computer.local...
>>>> On Wed, 29 Oct 2008 10:00:49 -0700, David
>>>> <david.colliver.NEWS@revilloc.removethis.com> wrote:
>>>>
>>>>> Thanks, so in my own example, it is the bluetooth.cs that needs to
>>>>> raise the
>>>>> event... and it is the form1.cs that needs to handle it.
>>>>>
>>>>> Where would the delegate go?
>>>>
>>>> Actually, you don't need to declare a delegate type anymore. You do
>>>> need to still declare your EventArgs sub-class, and that should go in
>>>> the same assembly with the Bluetooth class. For the delegate type, you
>>>> can use the generic EventHandler<T> class, where the type parameter is
>>>> your own EventArgs sub-class.
>>>>
>>>>> your MyClass I am assuming is the same as my form1.cs
>>>>
>>>> In his code sample, it appears to me that MyClass is equivalent to your
>>>> Bluetooth class. That is, it's the class that raises the event, not
>>>> the one that consumes it.
>>>>>
>>>>> I am also assuming that your SomeNormalCode() is what should be in my
>>>>> bluetooth.cs
>>>>
>>>> For his example, I believe that is correct.
>>>>
>>>> One note: the posted code for raising an event, both yours and sloan's,
>>>> is appropriate for single-threaded scenarios, but not multi-threaded.
>>>> Sloan's is better in that there is a dedicated event-raising method,
>>>> but even his has a threading bug in it. A correct method would look
>>>> like this:
>>>>
>>>> private void OnRootFolderEventArgs(RootFolderEventArgs arg)
>>>> {
>>>> EventHandler<RootFolderEventArgs> handler =
>>>> SomethingHappenedWithARootFolderEvent;
>>>>
>>>> if (handler != null)
>>>> {
>>>> handler(this, arg);
>>>> }
>>>> }
>>>>
>>>> By copying the delegate value before checking it for null, you ensure
>>>> that the value can't change from non-null to null between the time you
>>>> look at it and the time you try to use it.
>>>>
>>>> Note also that I've removed the "sender" argument to the method. This
>>>> should be an instance method, and the sender should always be "this",
>>>> so there's no need to pass it as an argument.
>>>>
>>>> One other note: in this example, the EventArgs sub-class itself is
>>>> being passed, but it would actually be very reasonable to have the
>>>> caller simply pass whatever data goes into the sub-class and then have
>>>> this method actually create the sub-class instance. This is especially
>>>> true if the sub-class only has a small number of data elements in it
>>>> (for example, there's just a single string).
>>>>
>>>> Pete
>>>
>>>
>>
>>
>
>


David

10/29/2008 6:56:00 PM

0

Magic...

That all builds now.

I have renamed FileReceivedEvent to FileReceived as well.

Thanks for your help guys.

--
Best regards,
Dave Colliver.
http://www.Ashfiel...
~~
http://www.FOCUSP... - Local franchises available


"Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message
news:op.ujst9cd18jd0ej@petes-computer.local...
> On Wed, 29 Oct 2008 11:21:36 -0700, David
> <david.colliver.NEWS@revilloc.removethis.com> wrote:
>
>> Cool...
>>
>> I was just coming back to the group after I had tried to implement it
>> (and
>> failed).
>>
>> In my form1.cs I have...
>>
>> bt.FileReceivedEvent += new EventHandler(BTFileReceived);
>>
>> [...]
>
> In addition to sloan's comment suggesting something you should
> double-check, the above can be changed to:
>
> bt.FileReceivedEvent += BTFileReceived;
>
> This does two things. First, it avoids the incorrect construction of an
> EventHandler instance. Even if you have the event type correct, you can't
> make an EventHandler delegate from a method that doesn't have Object or
> EventHandler as the second argument.
>
> The second thing it does is use the newer inferred delegate syntax, where
> the compiler looks at the destination type and automatically creates a
> delegate of the correct type for you. You could fix the line by changing
> "EventHandler" to "EventHandler<FileReceivedEventArgs>", but the newer
> syntax is a lot nicer IMHO.
>
> Once you've ensured that the event is declared correctly and changed the
> above line, it should compile.
>
> Finally, I'll point out that the .NET convention is for event names to not
> include the word "Event" at the end. It's not mandatory by any means, but
> following the .NET convention, your event would be named "FileReceived"
> instead.
>
> Pete