Reputation: 319
I am trying to connect biometric device in web application. I works fine in windows application but in web it throw error.
Windows-form.cs:
int nPort = Convert.ToInt32(textPort.Text);
int nPassword = Convert.ToInt32(textPassword.Text);
string strIP = ipAddressControl1.IPAddress.ToString();
bRet = axFP_CLOCK.SetIPAddress(ref strIP, nPort, nPassword);
if(!bRet)
{
return;
}
Form Designer:
((System.ComponentModel.ISupportInitialize)(this.axFP_CLOCK)).BeginInit();
this.axFP_CLOCK.Enabled = true;
this.axFP_CLOCK.Location = new System.Drawing.Point(476, 382);
this.axFP_CLOCK.Name = "axFP_CLOCK";
this.axFP_CLOCK.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axFP_CLOCK.OcxState")));
this.axFP_CLOCK.Size = new System.Drawing.Size(100, 50);
this.axFP_CLOCK.TabIndex = 11;
this.axFP_CLOCK.Visible = false;
((System.ComponentModel.ISupportInitialize)(this.axFP_CLOCK)).EndInit();
Likewise i try to connect in web application but it shows error: Webform1:
public AxFP_CLOCKLib.AxFP_CLOCK axFP_CLOCK;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bool bRet;
string ip= "192.168.1.109";
int nPort = Convert.ToInt32(5005);
int nPassword = Convert.ToInt32(0);
axFP_CLOCK = new AxFP_CLOCKLib.AxFP_CLOCK();
bRet = axFP_CLOCK.SetIPAddress(ref ip, nPort, nPassword);
if (!bRet)
{
Response.Write("success");
}
else
{
Response.Write("failure");
}
}
}
It throw error as
ActiveX control '87733ee1-d095-442b-a200-6de90c5c8318' cannot be instantiated because the current thread is not in a single-threaded apartment.
Dll:
public virtual bool SetIPAddress(ref string lpszIPAddress, int dwPortNumber, int dwPassWord)
{
if (this.ocx == null)
throw new AxHost.InvalidActiveXStateException(nameof (SetIPAddress), AxHost.ActiveXInvokeKind.MethodInvoke);
return this.ocx.SetIPAddress(ref lpszIPAddress, dwPortNumber, dwPassWord);
}
Anyone could help me to rectify this error?
Upvotes: 0
Views: 938
Reputation: 3681
You should run your method in a Thread
.
Something like below.
var thr = new Thread(new AxFP_CLOCKLib.AxFP_CLOCK().SetIPAddress(ref ip, nPort, nPassword));
thr.SetApartmentState(ApartmentState.STA);
thr.Start();
I am not very sure about it but annotating your Page_Load
should help as well.
[STAThread]
protected void Page_Load(object sender, EventArgs e)
{
// Code Goes here
}
Upvotes: 1
Reputation: 24957
The error message indicates that ActiveX control you're using requires STA (Single Threaded Apartment) state. You can set the apartment state of corresponding thread by using Thread.SetApartmentState()
method.
Assume you're already created a Thread
to wrap ActiveX instance like this:
var thread = new Thread(() => {
// other running processes inside thread
Application.Run();
});
Then you should specify apartment state of that thread to STA (ApartmentState.STA
) before using Start()
:
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
The reason behind this issue is most of .NET background threads (or worker APIs) will create new threads as multithreaded apartment state (MTA), while ActiveX control threads usually instantiated in STA mode.
Related issue:
Single-threaded apartment - cannot instantiate ActiveX control
Upvotes: 1