Консольное приложение C # все еще находится в памяти после выхода - асинхронная веб-служба - PullRequest
4 голосов
/ 07 марта 2012

Я действительно новичок в C # и .Net. Мой начальник попросил меня создать таймер с помощью асинхронного обратного вызова с помощью веб-службы. Я фактически создал его и заставил работать, но всякий раз, когда я закрываю окно консольного приложения, веб-служба все еще работает. Когда я перезапускаю приложение, оно запускает счетчик с 0, но переходит назад и вперед к числу от предыдущего запуска (который все еще находится в памяти).

mainMethod () увеличивает число на 1 каждые 10 секунд, а monitorMethod () считывает это число и возвращает строку.

Как мне остановить веб-службу и обнулять счетчик каждый раз, когда я закрываю окно консоли?

Надеюсь, это имеет смысл! Заранее спасибо!

Вот мой код.

Веб-сервис:

 public class Service1 : System.Web.Services.WebService
 {
    private int iTotal;
    private int iCurrent;

    [WebMethod]
    public void mainMethod()
    {
        iTotal = 42;
        iCurrent = 1;
        Application["iTotal"] = iTotal;
        Application["iCurrent"] = iCurrent;
        // sleep 10 seconds
        while (iCurrent <= iTotal)
        {
            Application["iCurrent"] = iCurrent;
            iCurrent++;
            System.Threading.Thread.Sleep(10000);                
        }
    }

    [WebMethod]
    public string monitorMethod()
    {
        iCurrent = int.Parse(Application["iCurrent"].ToString());
        iTotal = int.Parse(Application["iTotal"].ToString());
        if (iCurrent <= iTotal)
        {
            return iCurrent + " of " + iTotal;
        }
        else
            return "DONE";
    }
  }
}

Клиентская сторона

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Service1 client = new Service1(); //web service proxy
        client.mainMethodCompleted += new mainMethodCompletedEventHandler(client_mainMethodCompleted);

        if (Session["value"] == null)
        {
            Session["value"] = true;
        }

        if (!IsPostBack)
        {
            client.BeginmainMethod(AsyncCallback, null);
            string scriptFunction = "<script type=\"text/javascript\">function reSubmit(){ document.getElementById(\"" + btnProcessNext.ClientID + "\").click(); }</script>";
            this.RegisterClientScriptBlock("s1", scriptFunction);
            string script = "<script type=\"text/javascript\">setTimeout(\"reSubmit()\", 500);</script>";
            this.RegisterStartupScript("submit", script);
        }
        else
        {
            if (StringParseByMe(lblStatus.Text))
            {
                string scriptFunction = "<script type=\"text/javascript\">function reSubmit(){ document.getElementById(\"" + btnProcessNext.ClientID + "\").click(); }</script>";
                this.RegisterClientScriptBlock("s1", scriptFunction);
                string script = "<script type=\"text/javascript\">setTimeout(\"reSubmit()\", 500);</script>";
                this.RegisterStartupScript("submit", script);
            }
            else
                return;
        }
    }

    protected void btnProcessNext_Click(object sender, EventArgs e)
    {
        Service1 client = new Service1();
        string label = client.monitorMethod();
        Session["value"] = StringParseByMe(label);
        lblStatus.Text = label;
    }

    private bool StringParseByMe(string sparse)
    {
        if (sparse == "DONE")
            return false;

        string[] sparseArray = sparse.Split(' ');
        if (int.Parse(sparseArray[0]) == int.Parse(sparseArray[2]))
        {
            return false;
        }
        else
            return true;
    }

    void client_mainMethodCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        Service1 client = new Service1();
        client.EndmainMethod(ar);
    }

    public void AsyncCallback(IAsyncResult ar)
    {
    }
  }
}

Веб-страница

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
    Counter</h2>
    <br /><br /><br /><br /><br /><br />
<asp:Label ID="lblStatus" runat="server" Text="0 of -1" Font-Bold="True" 
    Font-Size="XX-Large" ForeColor="#CC0000"></asp:Label>
    <br /><br /><br /><br />
<asp:Button ID="btnProcessNext" runat="server" Text="Refresh" 
    onclick="btnProcessNext_Click" />
</asp:Content>

Ответы [ 3 ]

1 голос
/ 17 апреля 2012

Вы можете поместить кнопку на странице и написать логику остановки таймера в событии нажатия кнопки.После этого сгенерируйте скрипт для закрытия окна.

1 голос
/ 25 июня 2012

Даже если ваш клиент был прерван, асинхронный вызов mainMethod () все еще выполняется.Веб-служба не знает, что клиент ушел и продолжает работать.

При запуске второго клиента ваш код выполняет второй вызов mainMethod (), и теперь запущены два экземпляра.Оба пытаются обновить значения приложения iTotal и iCurrent.Вот почему цифры, кажется, подпрыгивают взад и вперед.

Вам нужно указать одному из потоков mainMethod () прекратить обновление значений приложения и прекратить работу.различные способы сделать это, но простой способ может быть что-то вроде этого:

[WebMethod]
public void mainMethod()
{
    iTotal = 42;
    iCurrent = 1;
    int iReference = (int)(Application["iReference"] ?? 0);
    ++iReference;
    Application["iReference"] = iReference;
    Application["iTotal"] = iTotal;
    while( (iCurrent <= iTotal) && ((int)(Application["iReference"]) == iReference) )
    {
        Application["iCurrent"] = iCurrent;
        ++iCurrent;
        System.Threading.Thread.Sleep( 10000 );
    }
}
0 голосов
/ 08 марта 2012

Рабочий процесс IIS, вероятно, все еще выполняется. Вам нужно будет убить запущенный w3wp.exe.

...