|
Hi,
server side, I got a class containing a method like this :
DB_Access_Class() : MashalByRefObject
public string Execute_Query(string query)
The DB_Access_Class instances got infinite lease time.
The goal is to share the same instance between all clients.
client side, I got a proxy (singleton mode) on a remote DB_Access_Class
Now, i want several Clients to be able to run Execute_Query at the same time.
I don't care (and would even prefer actually) if the client is locked while waiting for server answer.
But i don't know the best way to implement this and can't find any example on the net.
Is there any way to implement this without using asynchronous calls ?
Thanks,
Etienne.
|
|
|
|
|
You want the same client to execute the remote method multiple times at once? Or do you want multiple clients (i.e., multiple processes, perhaps even on different machines) to call it? The latter is already taken care of for you, which is why you should internally lock any resources if appropriate in your remote method.
If you want the same client to call it multiple times asynchronously, what's wrong with just calling it asynchronously? Otherwise, you can always create several threads, each of which would call it, but asynchronous method calls give you a little more control about when to receive the output of the method as well as polling options, which you'd have to add functionality for if you just used threads.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath Stewart wrote:
You want the same client to execute the remote method multiple times at once? Or do you want multiple clients (i.e., multiple processes, perhaps even on different machines) to call it? The latter is already taken care of for you, which is why you should internally lock any resources if appropriate in your remote method.
Indeed, it's about multiple clients, each of one doing 1 single call at a time. But from the tests i ran, here's what happens :
Client 1 calls remote_method
Client 2 calls remote method
remote_method takes 30 seconds to complete and returns result to Client 1
remote_method takes 30 seconds to complete and returns result to Client 2
So Client2 will wait 60 seconds before getting his result, which is not acceptable in my case where i'll have up to 15 clients calling the service. I need the server to treat requests simulteanously, which is why i need him to create a new thread on each call.
I just don't know the best way to implement this, and if i absolutely need asynchronous dialog using deleguates (which would require to have a MBR object client-side too, from what i understood)
Thanks for quick reply though, i really appreciate
Etienne.
|
|
|
|
|
The client really has nothing to do with yor problem in this case. If the server is configured as a singleton, it should be able to service both calls simultaneously unless you're using locks within the implementation itself, and asynchronous calls won't solve this problem since the whole point of locking resources is to synchronize access to them.
As far as what you have client side, it's still a proxy - an MBR object - that proxies calls to the remoting object. You can't proxy calls without that. The same is true for COM. You still have a proxy on the client which you get either through a common assembly with a shared interface or using a tool like soapsuds.exe.
A lot of this also depends on how the WKO is hosted on the server.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
There is something else going on behind the scenes if it really takes 60 seconds for the other second client to get an answer.
When remoting is configured on the server side as a Singleton there is one and only one AppDomain that holds the instance of the remoting object/function. Any number of clients can make calls into the remoting entry point without blocking. So I am wondering if there is something in the server that is blocking. In fact I wonder if you have race conditions. "Singleton" provides no "thread safety". Without further information its only speculation.
|
|
|
|
|
Thanks a lot for your answers.
Seems that i have a glitch in my code which makes the server unavailable to other clients while processing request from one of them.
Here is the simple example i'm trying to get working :
Interface
Server
Client
Projects
I must have something wrong in there, but i can't figure out what...
Code is really simple, i don't even have any exception handler or anything, but i could have missed something...
If you try it out, you'll see if you launch 2 clients and call request from both of them, one (the first) will be done in 10 seconds approximatively, and the other will take twice as much.
Thanks again for your interest !
Etienne.
|
|
|
|
|
Sorry for the delay in responding. Hopefully its not too far out of context.
Just glancing over your code I already see two places where deadlocks can occurs. This is why I said that Singleton have no thread safety at all. You don't need to put locks anywhere in your code if avoided using Singleton in the first place.
The fundemental problem is the lock inside of the the for loop. Don't put it there. Place around the entire loop and set.
I'm not sure why these are implemented this way but I implore you to reimplement the remote objects to be either SingleCall or client activated. Since you are trying to remember instance data, I recommend client activated.
|
|
|
|
|
hi, thanks again for your reply
I've been told on msdn newsgroup that singleton were supposed to spawn a new thread upon each call but that they actually did not, and this is apparently a known issue.
I've been adviced to look into genuine channels components, and they fit perfectly for what i need so i'll be using those
I have tried the same code i posted without any lock, to no avail.
I don't think the problem comes from locking, and i'd rather use singletons since i'm trying to build a DB access service, with several buffers acting as a proxy both for reading and writing.
(for instance, certain tables such as parameters tables will only be read once and for all and then stored in server memory, etc...)
And since i also need easy broadcasting (when parameters change) genuine channels do the work just fine.
Thanks again,
Etienne.
|
|
|
|
|
Hi,
Actually from what someone told me on MSDN newsgroup, the Singletons should spawn a new thread upon each call, but they do not. I've been told it was a known issue.
Etienne.
|
|
|
|
|
I am making custom print preview with PrintPreviewControl().I am having struggle with to change other pages from first page. I am trying to click a button to change next page,but I cant get anything change. I tried to search other ways and ran out of ideas. What are your suggestions?
public class CPrintPreviewDlg : System.Windows.Forms.Form
{
public CPrintPreviewDlg()//initialize
{
CustomPreviewDialog();
printPreviewDocument.PrintPage += new PrintPageEventHandler(Part_PreviewPage);
}
public void CustomPreviewDialog()
{
printPreviewDocument = new PrintDocument();
printPreviewDocument.DefaultPageSettings.Landscape = true;
printDocument.DefaultPageSettings.Landscape = true;
PrintPreviewCtrl = new PrintPreviewControl();
PrintPreviewCtrl.Enabled = true;
PrintPreviewCtrl.Name = "Detail Preview Page";
PrintPreviewCtrl.Dock = DockStyle.Fill;
PrintPreviewCtrl.UseAntiAlias = true;
Controls.Add(this.PrintPreviewCtrl);
PrintPreviewCtrl.Document = printPreviewDocument;
}
private void OnNextPage_Click(object sender, System.EventArgs e)//click button for //next page
{
printPreviewDocument.PrintPage += new PrintPageEventHandler(Part_PreviewPage); //dont work
}
private void Part_PreviewPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
if(PrintSurfaceViewList2.Count+1 <= 0 )//rid +1
{
return;
}
m_Grfx = e.Graphics;
m_PageSize.Height = (float)e.PageBounds.Height;
m_PageSize.Width = (float)e.PageBounds.Width;
float fCurrentHeight = (float)e.PageBounds.Height;
float fCurrentWidth = (float)e.PageBounds.Width;
e.HasMorePages = true;
if(m_nPage < PrintSurfaceViewList2.Count)
((CPrintSurfaceView)PrintSurfaceViewList2[m_nPage]).DrawPrintView(e.Graphics,fCurrentHeight,fCurrentWidth);
else
{
//PrintSurfaceView.GeneralInfoPrinting(e.Graphics,m_nPage,m_strJobName,m_strGroupName,m_strSection);
}
m_nPage++;
if(m_nPage >= PrintSurfaceViewList2.Count+1)
{
e.HasMorePages = false;
}
}
}
|
|
|
|
|
You can use the PrintPreviewControl.StartPage to get the page number. If you keep a state variable in your class you can determine what you should print based on this page number. For instance, if you were going to print 1 image per page and those images where stored in a list, you could use this as the index of the image in that list to print.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks!!!! it worked great when I am using PrintPreviewControl.StartPage for get the page number.
|
|
|
|
|
Iv'e used DataGrids to store data retrieved from an SQL statement. I was wondering if there was a way to manually specify columns, and to store data you specify (in my case, it would be retrived from a text file). If this is possible, can someone please direct me to an example of some sort, or at least explain how this would work?
Thanks in advance,
Jon
|
|
|
|
|
You can always explicitly define the style of a DataGrid using a DataGridTableStyle which has a collection of DataGridColumnStyle s. See the DataGrid.TableStyles collection property documentation in the .NET Framework SDK for more information and an example.
If you want to read-in data you can still use a DataSet which is easy to bind to a DataGrid . If your file is an XML document using a 2- or 3-element deep format (a "DataSet format"), then you can use DataSet.ReadXml to read it in and assign that to a DataGrid.DataSource as you would for a DataSet from a SQL command or adapter.
If it's a text file, you can either manually read it into a DataSet or read it in to another IList or IListSource implementation, which is really what the DataSource property wants. The example in the DataGridTableStyle.MappingName property documentation shows an example of data-binding to an array of objects with defined properties. Since an array implicitly inherits from System.Array - which implements IList - you can bind that as well.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi,
Can anyone tell me (via example is preferred) how to bind to a
CheckedListBox in a Windows Form? All the docs I've seen allow you to bind to a control property (i.e. TextBox.Text) to an instance variable property. How do you bind to both the 'ItemText' and 'Checked' values for each Item in a CheckedListBox?
TIA,
Matt
p.s. Also, I'm new here and I did look for a way to search all threads on the C# Discussion board but did not see how. Please advise.
|
|
|
|
|
The CheckedListBox does not support data-binding like that. First, you can add whatever objects you want to it. If the objects you're adding have ItemText and Checked properties, then you merely need to coordinate the event handlers for the CheckedListBox and set the Checked property of your object so that you can keep track of what's checked and what's not.
public class MyItem
{
private string itemText;
private bool checked;
public MyItem() : this(null, false)
{
}
public MyItem(string itemText, bool checked)
{
this.itemText = itemText;
this.checked = checked;
}
public string ItemText
{
get { return this.itemText; }
set { this.itemText = value; }
}
public bool Checked
{
get { return this.checked; }
set { this.checked = value; }
}
}
public void AddItem(MyItem item)
{
int index = checkedListBox1.Items.Add(item);
checkedListBox1.SetItemCheckState(index,
item.Checked ? CheckState.Checked : CheckState.Unchecked);
}
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
MyItem item = checkedListBox1.Items[e.Index];
item.Checked = e.NewValue == CheckState.Checked;
} You can always get the items out of CheckedListBox.Items whenever you want.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
This is my first project with a DataGrid.....
Is there any way to enable a full row select when the user clicks on a cell. By this I mean highlight the entire row when the user click on any cell. The reason I need this is that I do not want the user to have access to any contaxt menus other than the one I createdn and my context menu does not appear unless the full row is highlighted...
|
|
|
|
|
Not without creating custom DataGridColumnStyle classes (which could derive from either DataGridTextBoxColumn or DataGridBoolColumn so you don't have to redefine them), getting the row, and selecting that.
Really, though, this sounds like an issue with your code. If the context menu doesn't work without selecting the entire row, then your code isn't as robust as it should be.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi GS,
I had used the code below to achieve the above functionality in my last project. In DataGrid's Mouse Down event paste the below code:
private void DataGrid1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)<br />
{<br />
<br />
<br />
System.Drawing.Point pt = new Point(e.X, e.Y); <br />
<br />
DataGrid.HitTestInfo hti = DataGrid1.HitTest(pt); <br />
<br />
if ( e.Button ==MouseButtons.Left)
{<br />
if(hti.Type == DataGrid.HitTestType.Cell) <br />
<br />
{ <br />
<br />
DataGrid1.CurrentCell = new DataGridCell(hti.Row, hti.Column); <br />
<br />
DataGrid1.Select(hti.Row); <br />
<br />
} <br />
}<br />
<br />
}
Do reply, whether It solved your purpose?
Regards,
Jay
|
|
|
|
|
Works great, one thing though....were you able to highlight the selection also ?
My context menu shows up now, but the item is still not highlighted unless I click on the left most column of the DataGrid control. But this is trivial, the funtionalitly is there thanks for the help.
|
|
|
|
|
Hi GS,
Sorry, I was in hurry, that is why could not refer my last project minutely. Please paste the above code in MouseUp Event. The row will get highlighted whenever any cell is clicked.
Do revert back whether you could achieve the functionality.
[Note:tomorrow and day after tomorrow(28th and 29th) I am on leave.]
Regards,
Jay.
|
|
|
|
|
Works perfectly Jay, thank you.
|
|
|
|
|
I have an array made up of a cutom structure called sl1. How can I find the index of the sl1 object, in the array, that has a name property equal to value I'm searching for? 
|
|
|
|
|
In this case it'd be better to implement a list or collection (for instance, derive from CollectionBase ) and override the indexer or even add your own so that in the get accessor you enumerate your structs stored in the internal ArrayList (the List property inherited from CollectionBase , or your own if you just implement the necessary interfaces like IList , which inherits from ICollection , which inherits from IEnumerable ) and find the struct with the name property equal to the value you pass, like so:
public MyStruct this[string name]
{
get
{
if (name == null) throw new ArgumentNullException("name");
foreach (MyStruct s in List)
if (string.Compare(s, name) == 0) return s;
throw new ArgumentException("The structure was not found.", "name");
}
} Using just an array of your structs, you won't be able to do what you want unless you implement your own IComparer and call one of the Array.BinarySearch overloads which takes an IComparer implementation as a parameter.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Is there a generic way of saying "everything" in a parameter of an oleDbDataAdapter? For instance, if my query asks for all rows WHERE (Name = ?), and then later in my code somewhere I have
Adapter.SelectCommand.Parameters[Name].Value = "some name";
What could I put in place of "some name" that would just mean everything...or is it even possible? Also, what if Value wasn't expecting a string, what if it was a bool...what can I put to basically ignore this parameter? Thanks a bunch for any help. I tried looking it up, but I didn't know what to search for. 
|
|
|
|
|