dark-man
سه شنبه 16 اردیبهشت 1399, 21:06 عصر
با سلام خدمت همه اساتید. من یک Socket client در #C با استفاده از async methodهای مربوط به Socket نوشتم. بنا به نیازی که داشتم یک event به اسم OnReceive هم ایجاد کردم که بعد Socket.EndReceive بنا به شرایطی این event اجرا میشه. در کلاسی که OnReceive پیاده سازی شده بنا به شرایطی یک instance از روی یک فرم ایجاد می کنم و نمایش میدم. بعد از نمایش فرم با چند مورد مواجه میشم:
اگر از ()Show استفاده کنم فرم فریز میشه و بعد از چند دقیقه بسته میشه.
اگر از ()ShowDialog استفاده کنم فرم بدون مشکل باز میشه ولی در Main thread نیست.
امکان دسترسی به کنترلهای روی فرم مثلا" یک label یا امکان فراخوانی یک method در فرم رو ندارم.
ممنون میشم راهنماییم کنید با توجه به اینکه بخش مربوط به دریافت داده در Socket رو به صورت async نوشتم و در نهایت یک event اجرا میشه چه طور می تونم به فرمی که ساخته شده دسترسی داشته باشم.
نمونه کد:
// socket.cs
// event
public delegate void ReceiveDataEventHandler(object sender, string data);
public event ReceiveDataEventHandler OnReceiveData;
// call begin receive after connect complete
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
private void ReceiveComplete(IAsyncResult ar)
{
var rdm = (ReceiveDataModel)ar.AsyncState;
var _masterSocket = rdm.Socket;
var receiveLen = _masterSocket.EndReceive(ar);
if (receiveLen > 0)
{
var _rawData = Encoding.UTF8.GetString(rdm.Data, 0, receiveLen);
if (_rawData.EndsWith("EOF"))
{
rdm.DataStorage.Append(_rawData);
var responseData = rdm.DataStorage.ToString();
responseData = responseData.Replace("|EOF", "");
OnReceiveData?.Invoke(this, responseData);
rdm.DataStorage.Clear();
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
}
else
{
rdm.DataStorage.Append(_rawData);
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
}
}
else
{
if (_masterSocket.Connected)
{
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
}
}
}
manager.cs
// constructor
public Manager()
{
new Socket() = msMan;
msMan.OnReceiveData += new Socket.ReceiveDataEventHandler(OnReceiveData);
}
private void OnReceiveData(object sender, string data)
{
var form2 = new Form2();
// form2.Show();
// form2.ShowDialog();
}
اگر از ()Show استفاده کنم فرم فریز میشه و بعد از چند دقیقه بسته میشه.
اگر از ()ShowDialog استفاده کنم فرم بدون مشکل باز میشه ولی در Main thread نیست.
امکان دسترسی به کنترلهای روی فرم مثلا" یک label یا امکان فراخوانی یک method در فرم رو ندارم.
ممنون میشم راهنماییم کنید با توجه به اینکه بخش مربوط به دریافت داده در Socket رو به صورت async نوشتم و در نهایت یک event اجرا میشه چه طور می تونم به فرمی که ساخته شده دسترسی داشته باشم.
نمونه کد:
// socket.cs
// event
public delegate void ReceiveDataEventHandler(object sender, string data);
public event ReceiveDataEventHandler OnReceiveData;
// call begin receive after connect complete
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
private void ReceiveComplete(IAsyncResult ar)
{
var rdm = (ReceiveDataModel)ar.AsyncState;
var _masterSocket = rdm.Socket;
var receiveLen = _masterSocket.EndReceive(ar);
if (receiveLen > 0)
{
var _rawData = Encoding.UTF8.GetString(rdm.Data, 0, receiveLen);
if (_rawData.EndsWith("EOF"))
{
rdm.DataStorage.Append(_rawData);
var responseData = rdm.DataStorage.ToString();
responseData = responseData.Replace("|EOF", "");
OnReceiveData?.Invoke(this, responseData);
rdm.DataStorage.Clear();
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
}
else
{
rdm.DataStorage.Append(_rawData);
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
}
}
else
{
if (_masterSocket.Connected)
{
_masterSocket.BeginReceive(rdm.Data, 0, ReceiveDataModel.DataSize, SocketFlags.None, new AsyncCallback(ReceiveComplete), rdm);
}
}
}
manager.cs
// constructor
public Manager()
{
new Socket() = msMan;
msMan.OnReceiveData += new Socket.ReceiveDataEventHandler(OnReceiveData);
}
private void OnReceiveData(object sender, string data)
{
var form2 = new Form2();
// form2.Show();
// form2.ShowDialog();
}