程序 A、B、C,A是系统内核程序,负责权限管理、系统配置等操作,B and C是实现具体功能的应用程序。 为了提高效率,A、B、C这三个程序中使用了缓存技术,例如:第一次从"系统配置"表中检索出数据后,将结果提交给静态变量"X"(HashTable类型),下次再访问"系统配置'的数据就从静态变量"X"中直接读取。 问题来了,用户通过程序A修改系统配置后,程序B、C各自的静态变量"X"没有被更新,B、C就无法按照A修改后的系统配置执行。 解决这个问题需要程序A、B、C共享一份缓存数据,请问该用什么方法实现?效率如何?解决后马上给分!!!
首先谢谢你们的回答,你们可能还没看清题目的意思,首先A、B、C三个程序有各自的缓存(Hashtable变量),程序A修改系统配置后当然要刷新自身的缓存,但是却无法刷新程序B和C的缓存,因为他们不是一个程序,各自的变量也是相互独立无法控制的。
cenchure(达到)、livode(啊水)
谢谢你们,这正是我所想的结果。请问,消息队列或者事件通知的效率如何?事件通知的功能好像挺强啊。最重要的是他们怎么实现,麻烦再说明一下。
using System;
/// <summary>
/// Gobal 的摘要说明。
/// </summary>
public class Gobal
{
public static string user;//用户名
public static string ipaddress;//ip地址
public static string port;//端口
public Gobal()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
}
用user的时候直接Gobal.user,而不用Gobal gg=new Gobal();,这样,无论你在那里用Gobal.user,都是统一的。
lz要不再弄个Web services进行配置和读取,如何?
不过只要能实现目标,差点又有什么不可以呢?!另外,在<<WINDOWS核心编程>>里面似乎讲到了一种叫内存映射文件的技术.
楼主,
你设计的思路跟偶一样,有一些不同的是,
偶不是用静态变量,而是A、B、C各有一个public 的 Table 型的属性(A、B、C继续自同一interface),A是主程序,由A调用B、C,调用时把这个public的属性传给B、C,由于是引用类型,所以他们实际指向同一个Table,只需维护一份table。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;namespace MessageQ
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Messaging.MessageQueue helpRequestQueue;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtName;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtMessage;
private System.Windows.Forms.Button sendMessage;
private System.Windows.Forms.Button refreshMessages;
private System.Windows.Forms.Button purgeMessages;
private System.Windows.Forms.CheckBox highPriority;
private System.Windows.Forms.DataGrid messageGrid;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null; public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent(); //
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
} /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.helpRequestQueue = new System.Messaging.MessageQueue();
this.label1 = new System.Windows.Forms.Label();
this.txtName = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.txtMessage = new System.Windows.Forms.TextBox();
this.sendMessage = new System.Windows.Forms.Button();
this.refreshMessages = new System.Windows.Forms.Button();
this.purgeMessages = new System.Windows.Forms.Button();
this.highPriority = new System.Windows.Forms.CheckBox();
this.messageGrid = new System.Windows.Forms.DataGrid();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.messageGrid)).BeginInit();
this.SuspendLayout();
//
// helpRequestQueue
//
this.helpRequestQueue.MessageReadPropertyFilter.Priority = true;
this.helpRequestQueue.Path = "FormatName:DIRECT=OS:gaoxiaoyong\\private$\\helprequest";
this.helpRequestQueue.SynchronizingObject = this;
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 328);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(40, 16);
this.label1.TabIndex = 0;
this.label1.Text = "名称:";
//
// txtName
//
this.txtName.Location = new System.Drawing.Point(64, 328);
this.txtName.Name = "txtName";
this.txtName.Size = new System.Drawing.Size(96, 21);
this.txtName.TabIndex = 1;
this.txtName.Text = "";
//
// label2
//
this.label2.Location = new System.Drawing.Point(192, 328);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(48, 16);
this.label2.TabIndex = 2;
this.label2.Text = "消息:";
//
// txtMessage
//
this.txtMessage.Location = new System.Drawing.Point(248, 328);
this.txtMessage.Multiline = true;
this.txtMessage.Name = "txtMessage";
this.txtMessage.Size = new System.Drawing.Size(384, 72);
this.txtMessage.TabIndex = 3;
this.txtMessage.Text = "";
//
// sendMessage
//
this.sendMessage.Location = new System.Drawing.Point(344, 416);
this.sendMessage.Name = "sendMessage";
this.sendMessage.Size = new System.Drawing.Size(80, 24);
this.sendMessage.TabIndex = 4;
this.sendMessage.Text = "发送消息";
this.sendMessage.Click += new System.EventHandler(this.sendMessage_Click);
//
// refreshMessages
//
this.refreshMessages.Location = new System.Drawing.Point(448, 416);
this.refreshMessages.Name = "refreshMessages";
this.refreshMessages.Size = new System.Drawing.Size(80, 24);
this.refreshMessages.TabIndex = 5;
this.refreshMessages.Text = "刷新消息列表";
this.refreshMessages.Click += new System.EventHandler(this.refreshMessages_Click);
//
// purgeMessages
//
this.purgeMessages.Location = new System.Drawing.Point(552, 416);
this.purgeMessages.Name = "purgeMessages";
this.purgeMessages.Size = new System.Drawing.Size(80, 24);
this.purgeMessages.TabIndex = 6;
this.purgeMessages.Text = "清除消息列表";
this.purgeMessages.Click += new System.EventHandler(this.purgeMessages_Click);
//
// highPriority
//
this.highPriority.Location = new System.Drawing.Point(24, 368);
this.highPriority.Name = "highPriority";
this.highPriority.Size = new System.Drawing.Size(88, 16);
this.highPriority.TabIndex = 7;
this.highPriority.Text = "高优先级";
//
// messageGrid
//
this.messageGrid.DataMember = "";
this.messageGrid.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.messageGrid.Location = new System.Drawing.Point(16, 16);
this.messageGrid.Name = "messageGrid";
this.messageGrid.Size = new System.Drawing.Size(616, 296);
this.messageGrid.TabIndex = 8;
//
// button1
//
this.button1.Location = new System.Drawing.Point(32, 416);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(112, 24);
this.button1.TabIndex = 9;
this.button1.Text = "利用代码创建队列";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(160, 416);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(64, 24);
this.button2.TabIndex = 10;
this.button2.Text = "清除";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(648, 453);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.messageGrid);
this.Controls.Add(this.highPriority);
this.Controls.Add(this.purgeMessages);
this.Controls.Add(this.refreshMessages);
this.Controls.Add(this.sendMessage);
this.Controls.Add(this.txtMessage);
this.Controls.Add(this.label2);
this.Controls.Add(this.txtName);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.messageGrid)).EndInit();
this.ResumeLayout(false); }
#endregion /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
{
System.Messaging.Message theMessage =
new System.Messaging.Message(txtMessage.Text);
theMessage.Label = txtName.Text;
if (highPriority.Checked)
theMessage.Priority = System.Messaging.MessagePriority.Highest;
else
theMessage.Priority = System.Messaging.MessagePriority.Normal;
helpRequestQueue.Send(theMessage);
DisplayMessages(); }
private void DisplayMessages()
{
DataTable messageTable = new DataTable();
messageTable.Columns.Add("Name");
messageTable.Columns.Add("Message");
messageTable.Columns.Add("Priority");
System.Messaging.Message[] messages;
messages = helpRequestQueue.GetAllMessages();
System.Messaging.XmlMessageFormatter stringFormatter;
stringFormatter = new System.Messaging.XmlMessageFormatter(
new string[] {"System.String"});
for (int index = 0; index < messages.Length; index++)
{
messages[index].Formatter = stringFormatter;
messageTable.Rows.Add(new string[] {
messages[index].Label,
messages[index].Body.ToString(),
messages[index].Priority.ToString() });
}
messageGrid.DataSource = messageTable;
}
private void DisplayMessages2()
{
try
{
DataTable messageTable = new DataTable();
messageTable.Columns.Add("Name");
messageTable.Columns.Add("Message");
messageTable.Columns.Add("Priority");
System.Messaging.Message[] messages;
messages = MyPrivateQueue.GetAllMessages();
System.Messaging.XmlMessageFormatter stringFormatter;
stringFormatter = new System.Messaging.XmlMessageFormatter(
new string[] {"System.String"});
for (int index = 0; index < messages.Length; index++)
{
messages[index].Formatter = stringFormatter;
messageTable.Rows.Add(new string[] {
messages[index].Label,
messages[index].Body.ToString(),
messages[index].Priority.ToString() });
}
messageGrid.DataSource = messageTable;}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void refreshMessages_Click(object sender, System.EventArgs e)
{
DisplayMessages(); } private void purgeMessages_Click(object sender, System.EventArgs e)
{
helpRequestQueue.Purge();
DisplayMessages(); } private void button1_Click(object sender, System.EventArgs e)
{
try
{
System.Messaging.Message theMessage =
new System.Messaging.Message(txtMessage.Text);
theMessage.Label = txtName.Text;
if (highPriority.Checked)
theMessage.Priority = System.Messaging.MessagePriority.Highest;
else
theMessage.Priority = System.Messaging.MessagePriority.Normal;
MyPrivateQueue.Send(theMessage);
DisplayMessages2();}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
} }
System.Messaging.MessageQueue MyPrivateQueue;
private void Form1_Load(object sender, System.EventArgs e)
{
try
{
// System.Messaging.MessageQueue.Create(@".\Private$\MyPrivateQueue");
MyPrivateQueue =
new System.Messaging.MessageQueue(@".\Private$\MyPrivateQueue");
MyPrivateQueue.MessageReadPropertyFilter.Priority=true;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
} private void button2_Click(object sender, System.EventArgs e)
{
MyPrivateQueue.Purge();
DisplayMessages2();
} }
}
1. 系统内核(底层类库或者叫框架,它包含WebUI、多数据库支持、用户、部门、权限、系统配置、系统集成等所有通用功能的底层类)
2. 系统内核应用程序(负责通用功能的管理)
3. 应用程序A(例如OA)
4. 应用程序B(例如库存)
5. 应用程序C(例如CRM)
6. 应用程序D(例如内外网CMS)
N. ...
所有的应用程序包括"系统内核应用程序"在内都要引用底层类库,我想在底层类库中实现数据缓存功能。 yuesongboy(可极),数据缓存能否跨应用程序呢? leo2003【健者天行】,谢谢,你的思路我差不多理解了,但我对C#不是很熟,能否贴一份演示代码? Ivony(),我做的是系统,不是独立的应用程序,所以分为多个应用程序是必要的。不知道你说的程序动态加载方法在我的框架结构里能否实现?我对C#了解得不够透彻,请指教。 GXY2005(不好!我看見豬在天上飛),呵呵,谢谢支持啊。我先测试一下,解决后一定加分!每个人都少不了!我会多发几个帖子的! TheRule(绝非偶然),你给的代码我测试了,在一个应用程序中是可以的,但还是无法跨应用程序,你所说的“常驻内存的东东”应该如何实现?
大家再帮帮忙,不够我可以再发帖子加分!
我希望大家一起讨论个比较完美的解决方案,最好把分布式应用程序的解决方案也讨论出来。做两套方案,第一:单机多应用程序,第二:分布式应用程序。然后做成底层类库,以后用起来就方便了。
楼主是web form,不知楼主是怎样调出各应用程序B、C的。
偶是Win From,是程序(框架)A是Exe,各应用程序如B、C都编译成DLL,调用时动态装载各DLL。
偶的代码,希望对楼主有用:1.定义一个类(e.g:名为SysUser),类包括你想保存的各种属性
private class SysUser{}2.在主程序A中实例化 SysUser:_loginUser ;
private SysUser _loginUser ;
......3.在主程序A的ShowForm方法(调用别的DLL,如B、C)中,传递已实例化的_loginUser变量。
由于_loginUser是引用类型, B、C和A都指向同一内存地址。
frmB.LoginUser = this._loginUser;//在frmB的内部就可能使用LoginUser的值了。
通过这个地址启动应用程序B:http://localhost/B/index.aspx 在VS.NET中,A和B是两个不同的项目,他们的共同点是调用了内核的类库文件(就叫他Core.dll吧),Core.dll里封装了“系统配置”的缓存处理。 当时我只是简单的认为把数据缓存做成静态变量就可以,测试后发现这个静态变量实际上只是在单一的应用程序中共享的,应用程序之间并不共享。 刚才搜索了老半天发现P/Invoke可以实现管道,好像能时间进程间的数据通信,我想用这个方法试试,能否一块想个办法?
public struct test
{
public int data
}
public unsafe void test( byte[] buffer )//buffer从文件映射到内存的数据
{
fixed ( byte *pdata = &buffer[0] )
{
test *t = (test *)pdata;
}
}
ChinsesLiuxm
在B,C中各建一个refresh.aspx,专门负责刷新HashTable,每次A程序修改配置后,建一个webclient对象,用这个对象调用B和C中refresh.aspx。
可以去看看。
大家说说,有没有讲数据共享, .net remoting 比较好的书籍/文章啊.
谢谢!
“如果互相进行通信的所有进程在同一台计算机上,上面提到的所有机制(注:包括RPC、COM、OLE、DDE、窗口消息、剪贴板、邮箱、管道和套接字)均使用内存映射文件从事他们的烦琐工作。如果要求达到较高的性能和较小的开销,内存映射文件是举手可得的最佳机制。”(BY Jeffrey Richter)
上面还有一个使用内存映射文件通信的例子,主要用到了下列API函数:
CreateFileMapping 创建内存映射文件
CloseHandle 关闭返回句柄的任何对象
MapViewOfFile 在本线程的地址空间建立内存映射文件的视图
UnmapViewOfFile 与上面相反
OpenFileMapping 打开一个内存映射文件
还好不太多,一个一个DLLIMPORT也不是特别麻烦。如果不在同一台计算机,用WEB SERVICE估计比较方便,效率可能就不太高了。
我正在写类库。