Implement destructor/dispose in code behind - c#

I use asp net 4.5.
I have Marker.aspx page and code behind page Marker.aspx.cs.
Whenever postback occurred Page_Load function is fired in code behind and GeoMarkup class created.
GeoMarkup markupManager;
protected void Page_Load(object sender, EventArgs e)
{
markupManager = new GeoMarkup("constans",
"mapName",
null);
}
Whenever postback is implemented I need destructor to be fired and put inside destructor this row:
markupManager.Dispose();
My question is how can I implement destructor in code behind?;

Your code behind class is a subclass of Page which has a virtual Dispose method.
You should override that method in your code behind
public override void Dispose()
{
if (markupManager != null) {
markupManager.Dispose();
markupManager = null;
}
}
The HTTP pipeline will call Dispose on classes when they are no longer needed for the processing of the current HTTP request.

Related

Xamarin.Android, How to call another method from another .cs file

Needed some help here, so I tried to run method from another .cs, I had the following code running in my mainActivity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
startGame();
}
public void startGame()
{
firstNum = FindViewById<TextView>(Resource.Id.tvFirstNum);
secondNum = FindViewById<TextView>(Resource.Id.tvSecondNum);
firstNum.Text = Convert.ToString(2);
secondNum.Text = Convert.ToString(2);
}
Heres the thing, I tried to run the code from another CS file
private void BtnRestart_Click(object sender, EventArgs e)
{
MainActivity mp = new MainActivity();
mp.startGame();
}
However I got the error of
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.app.Activity.findViewById(int)' on a null
object reference
Does anyone know why?
Thanks!
You are instantiating your MainActivity class yourself, which does not load the accompanying Layout. That's because the lifecycle methods that Android uses aren't called, so your OnCreate method will never fire (which usually handles the layout). Therefore the FindViewById will return a null value.
A note: You shouldn't call views from another class (especially if it's another Activity) like you are trying to do here. If you still want to call this from another class, you can pass the Activity as a parameter, but I wouldn't recommend that approach.
I would recommend you to read the Activity Lifecycle documentation.

Calling non-static void from another cs file

I am new to C# and I probably know somebody asked the same thing here before. I found some info on google and here on stackoverflow , but I just can't get it to work properly.
I need to call a non-static void (MainPage.cs / class MainPage) .
public async void UploadThat()
{
.
.
.
.
Messagebox.Show("Hello there!");
}
from a another cs file (WebServer.cs).
I tried to do it like this in Webserver.cs file:
using MainPage;
.
.
.
public MainPage test;
and than call: test.UploadThat();
It complied my app successfully, but it does not work.
Thanks in advance..
There are several ways to solve this. Here are the two most common:
call the method directly; since the method is not static, you need a reference to the MainPage instance. That instance could be passed to the constructor of WebServer, and stored as a field. Note that this approach causes high coupling between the classes, which is usually not desirable.
in WebServer.cs:
private readonly MainPage _mainPage;
public WebServer(MainPage mainPage)
{
_mainPage = mainPage;
}
...
_mainPage.UploadThat();
in MainPage.cs:
WebServer ws = new WebServer(this);
expose an event in the WebServer class; have MainPage handle this event by calling UploadThat; when WebServer wants to call UploadThat, it just raises the event, and MainPage takes care of it. This way, WebServer doesn't have to know anything about MainPage.
in WebServer.cs:
public event EventHandler UploadRequested;
private void OnUploadRequested()
{
EventHandler handler = UploadRequested;
if (handler != null)
handler(this, EventArgs.Empty);
}
...
// instead of calling UploadThat directly
OnUploadRequested();
in MainPage.cs:
WebServer ws = new WebServer();
ws.UploadRequested += ws_UploadRequested;
...
private void ws_UploadRequested(object sender, EventArgs e)
{
UploadThat();
}
As a side note, you should avoid async void methods, except for event handlers or method overrides. This article explains why.

Postback delegate is null

I am building server control with custom events and as example used this MSDN reference.But events are never fired while postback - clickEventDelegate is always null:
if (clickEventDelegate != null)
{
clickEventDelegate(this, e);
}
Here is how I add delegate:
if (!Page.IsPostBack)
{
.....
MYCONTROL.LeftClick+= FUNCTION;
}
Any ideas?
You did not post enough of your code to find out why your event is null. But I am gonna list the standard pattern.
This is how you define an argument class for your custom event:
public class MyEventArgs : EventArgs
{
private string MyField { get; private set; }
public MyEventArgs(string myField)
{
MyField = myField;
}
}
This is how you define a custom event:
public event EventHandler<MyEventArgs> MyEvent;
This is how you write an event raiser in the same class as the event:
protected virtual void OnMyEvent(MyEventArgs e)
{
EventHandler<MyEventArgs> myEvent = MyEvent; // for thread safety
if (myEvent != null)
{
myEvent(this, e);
}
}
This is how you raise the event in the class it is defined in (or a derived class):
OnMyEvent(new MyEventArgs("Test"));
This is how you react to the event in a derived class:
protected override void OnMyEvent(MyEventArgs e)
{
// TODO: Here you react to your event.
base.OnMyEvent(e);
}
This is how you register on the event in a foreign class:
otherClass.MyEvent += delegate(object sender, EventArgs e)
{
// TODO: Here you react to your event.
};
The other answer just explains how events work but is completely ignoring the main point of the question: Delegate is null during a postback
The answer was quite simple. Just subscribe to your event every times even during Postback, so you just had to remove your condition if (!Page.IsPostBack)
MYCONTROL.LeftClick+= FUNCTION;
I know this is a very old question and there is no way you are still searching for the answer. But when I read
You did not post enough of your code to find out why your event is
null
from the previous answer I couldn't let this wrong statement like this.
EDIT:
To add more explanations, every time the server returns the final page to be rendered in the browser it then looses the state of this particular connection. Imagine if the server should keep in memory all connections with their associated states, you have maybe thousands of users a day, and also when to "clean" this memory?
So no that won't be doable that's why they created the ViewState so the browser can send previous information to the server. However this ViewState can save values of some variables or objects but doesn't save the binding between an event and its delegate(s).
Back to concrete examples. If you do this
<asp:Button runat="server" ID="ButtonTest" OnClick="buttonTest_Click" Text="test" />
The subscription to the event is made internally by ASP.NET on a very early stage in the life cycle before you reach the page's Page_Load. You can read about the ASP.NET life cycle here
If you assign the event handler like this
<asp:Button runat="server" ID="ButtonTest" Text="test" />
and on your page's server side:
protected void Page_Load(object sender, EventArgs e)
{
ButtonTest.Click += ButtonTest_Click;
}
It will work the same except that the subscription is made a bit later.
But if instead you decorate it in a condition
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ButtonTest.Click += ButtonTest_Click;
}
}
This won't work because the event handler has not been assigned. Remember that your server forgot the state of this particular connection and has to initialize everything at each HTTP POST request (PostBack).
This is exactly like in the sample code of your question, so as you can see events are working the same on native ASP.NET controls or custom ones you declared.

Event handler memory leak using ChildWindows

I just want to ensure that the code below will not be causing the ChildWindow Login in this case to never be collected by the GC. Just to clarify the sample this comes from a silverlight page that is inherited by all other pages therefore the virtual void pageloaded method.
public class MyPage : Page
{
// Executes when the user navigates to this page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_user = App.AuthenticatedUser;
if (!_user.IsValid)
{
Login loginWindow = new Login(_user);
loginWindow.Closed += new EventHandler(PageLoaded);
loginWindow.Show();
}
else
PageLoaded(this, e);
}
//to be overridden by the pages extending this page control
protected virtual void PageLoaded(object sender, EventArgs e) { }
Thanks for your help.
This is fine. The loginWindows's Close event knows of your handler, not the other way around, so the form will not have any ties preventing the GC from picking it up.
Unregistering event handlers becomes important if the object your event is defined on will persist in the application for a long time (and you do not want the event handler association to persist for the same duration).

Assign delegate event handler from dynamically added child control

I have a control that handles commenting. In this control, I have set a delegate event handler for sending an email.
I then have various types of controls, e.g. blog, articles etc, each of which may or may not have the commenting control added (which is done dynamically with me not knowing the id's), i.e. the commenting control is added outside this control. Each of these controls handles it's emailing differently(hence the event).
What I'm trying to determine, is how to assign the event in the parent control. At the moment, I'm having to recursively search through all the controls on the page until I find the comment control, and set it that way. Example below explains:
COMMENTING CONTROL
public delegate void Commenting_OnSendEmail();
public partial class Commenting : UserControl
{
public Commenting_OnSendEmail OnComment_SendEmail();
private void Page_Load(object sender, EventArgs e)
{
if(OnComment_SendEmail != null)
{
OnComment_SendEmail();
}
}
}
PARENT CONTROL
public partial class Blog : UserControl
{
private void Page_Load(object sender, EventArgs e)
{
Commenting comControl = (Commenting)this.FindControl<Commenting>(this);
if(comControl != null)
{
comCtrol.OnComment_SendEmail += new Commenting_OnSendMail(Blog_Comment_OnSendEmail);
}
}
}
Is there an easier way?
EDIT:
The reason I ask is that if I search from this.Page as the initial control, I am worried about time taken to search down the control tree to find it. Each different type of page would be different in how many control it would have. On some testing, it returns back quite quickly the result.
You could override the AddedControl event of your Blog class and check if the added control is instance of type Commenting. Something like:
public partial class Blog : UserControl {
protected override void AddedControl(Control control, int index) {
base.AddedControl(control, index);
Commenting commentingControl = control as Commenting;
if (commentingControl == null) return;
commentingControl.OnComment_SendEmail += new Commenting_OnSendMail(Blog_Comment_OnSendEmail);
}
}
Of course, you can put this code on a base class of all your "commentable" user controls and have an abstract method to actually handle the event.
Just one thing: the AddControl event happens AFTER the Page_Load, so be careful.
Cheers,
André

Categories

Resources