【问题标题】:C# Console Application still in memory after exit - Asynchronous Web Service退出后 C# 控制台应用程序仍在内存中 - 异步 Web 服务
【发布时间】:2012-03-07 18:14:31
【问题描述】:

我真的是 C# 和 .Net 的新手。我的老板让我使用 Web 服务使用异步回调创建一个计时器。我实际上创建了它,并让它工作,但每当我关闭控制台应用程序窗口时,Web 服务仍在运行。当我重新运行应用程序时,它会从 0 开始计数器,但会来回跳转到上一次运行的数字(仍在内存中)。

mainMethod() 每 10 秒将数字加 1,monitorMethod() 读取该数字,并返回一个字符串。

如何在每次关闭控制台窗口时停止 Web 服务并将计数器重置为 0?

我希望这是有道理的!提前致谢!

这是我的代码。

网络服务:

 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>

【问题讨论】:

  • 正在关闭应该停止服务的控制台窗口?
  • 是的,它假设完全停止并重置。
  • 你为什么使用应用程序状态?
  • 你发起的话题永远不会结束。你还有什么期待?你的代码正在做它应该做的事情。

标签: c# .net web-services asynchronous


【解决方案1】:

可以在页面上放置一个按钮,在按钮的点击事件中编写停止定时器的逻辑。之后,生成一个脚本来关闭窗口。

【讨论】:

    【解决方案2】:

    即使您的客户端已终止,对 mainMethod() 的异步调用仍在进行中。 Web 服务不知道客户端已消失并继续运行。

    通过启动第二个客户端,您的代码会再次调用 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 );
        }
    }
    

    【讨论】:

      【解决方案3】:

      IIS 工作进程可能仍在运行。您需要终止正在运行的 w3wp.exe。

      【讨论】:

      • 是的,但是我可以在我的代码中添加什么,让它在我关闭控制台窗口时停止。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多