【问题标题】:WCF web service singleton - odd behaviourWCF Web 服务单例 - 奇怪的行为
【发布时间】:2023-03-21 09:50:01
【问题描述】:

我创建了一个单例 WCF Web 服务,它在托管时始终运行一个后台线程。第一种方法在后台线程中启动一个函数,该函数检查共享数据,另一种方法更新该数据。它工作正常,突然开始表现得很奇怪。同时,代码没有重大变化。 WCF Web 服务托管在 Visual Studio Development Server、VS2008、3.5 框架、Win XP SP3 中,如果它托管在 IIS 7 上的 Vista 中,也会发生同样的情况。

这里是简化的代码

服务:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    void Configure(XElement configuration);

    [OperationContract]
    void UpdateData(string data);               
}

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public partial class Service1 : IService1
{
    List<string> stringCollection = new List<string>();
    bool running;
    Thread workerThread;

    public void Configure(XElement configuration)
    {
        //add string elements to the stringCollection based on configuration
        ParseConfiguration(); //implementation is irrelevant

        //start background thread
        workerThread = new Thread(WorkerFunction);
        running = true;
        workerThread.Start();
    }

    public void UpdateData(string data)
    {
        //adds string data to stringCollection
        stringCollection.Add(data);
    }
}

public partial class Service1 : IService1
{
    private void WorkerFunction()
    {
        while(running)
        {
            //check stringCollection
            Thread.Sleep(500);
        }
    }
}

客户:

//Configure() is called first and only once from client
Xelement configuration = Xelement.Load("configuration.xml");
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
client.Configure(configuration);
client.Close();

//UpdateData is called repeatedly from client
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
client.UpdateData("some string");
client.Close();

在调试时,我注意到了几件事。在 Configure() 在新线程中启动 WorkerFunction() 之后,线程会存活一秒左右,而 WorkerFunction() 可以访问在 Configure() 中配置的 stringCollection。当客户端第一次调用 UpdateData() 方法时,该方法具有空 stringCollection(不包含从 Configure() 方法添加的数据),就好像它没有共享一样,而 stringCollection 在每次 UpdateData() 调用之间保留其数据。例如:

//stringCollection after Configure()
{"aaa","bbb","ccc"}

//stringCollection after UpdateData("xxx")
{"xxx"}

//stringCollection after UpdateData("yyy")
{"xxx", "yyy"}

//after I run Client application again and call Configure()
//the data is preserved only here
{"xxx", "yyy","aaa", "bbb", "ccc"}

如果我在调试时在线程窗口中挂起具有最高优先级的线程,那么后台线程会像它应该做的那样保持活动状态,但我会得到与上面相同的结果。 WorkerFunction() 有它自己的 stringCollection 实例,而 UpdateData() 有另一个实例。我不知道具有最高优先级的线程与我的后台线程有什么关系,但它似乎对它有不良影响。服务应该是单例的,但它不像一个。

干杯

【问题讨论】:

  • 您已经省略了代码中最重要的部分!那么//adds string data to stringCollection是什么?
  • 哦,是的,对不起... stringCollection.Add(data);
  • 问题已解决。我试图将本地配置文件保存到服务 dll 所在的 bin 文件夹中。我省略了那部分代码,因为我认为它没有问题(服务正常保存文件并且没有抛出异常)。我更改了文件夹,一切都很好。

标签: multithreading wcf web-services singleton


【解决方案1】:

很高兴看到您的问题已解决。

但是,我认为你应该看一下你的代码,它似乎比它需要的复杂。

您正在使用单例,但对单例的每次调用都在创建一个新线程。

为什么不使用单例并让 IIS 处理线程呢?

【讨论】:

  • 看起来是这样,因为它是一个简化版本。通常我会在启动新线程之前检查线程是否正在运行。我可以以某种方式初始化托管在 IIS 中的单例吗?如果我的后台线程可以在创建服务对象时自动启动,那就太好了。
  • 你可以有一个单例类,见msdn.microsoft.com/en-us/library/ff650316.aspx
猜你喜欢
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
  • 2012-07-13
  • 1970-01-01
相关资源
最近更新 更多