PDA

View Full Version : کار با BeginInvoke و خطای مربوطه



sh
شنبه 09 اردیبهشت 1385, 20:46 عصر
در یه برنامه که قراره وزن باسکول رو بخونه و در یه فرم نشون بده با تظیمات کامپوننت سریال پورت ویژوال استدیو موفق به خوندن وزن در هر لحظه شدم در مثالی که از کدهای اون استفاده کرده بودم گفته بود که از متد DataReceived کامپوننت SerialPort حتما باید با استفاده از یک Delegate مقدار رو در هر لحظه به یه TextBox داد من این کار رو طبق کد زیر انجام دادم و مشکلی نیست ولی به محض خروج از فرم پیغام خطای زیر رخ میده

Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

چون تا حالا از Invoke استفاده نکردم اگر ممکنه دوستانی که کار کردند یه توضیحی در این خصوص بدن که چرا اینجا از Delegate و Invoke استفاده شده و راه حل این مشکل چیه

ممنون



PublicDelegateSub myDelegate()


PublicSub updateTextBox()
With TextBox1
.Clear()
.AppendText(serialPort.ReadExisting)
EndWith
EndSub
----------------------------------------------------
PrivateSub DataReceived(ByVal sender AsObject, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles serialPort.DataReceived
TextBox1.Invoke(New myDelegate(AddressOf updateTextBox), NewObject() {})
EndSub

SabaSabouhi
پنج شنبه 01 شهریور 1386, 10:09 صبح
با سلام
حدس مى‌زنم دلیل این مشکل این هست که ارسال اطلاعات به صورت مداوم انجام مى‌شه و هنگام بسته شدن فرم حداقل یک‌بار این وقفه پس از نابودى Handle پنجره‌ى شما فراخوانى مى‌شه.
به احتمال زیاد مشکل شما هم با قرار دادن یک try catch در رویه‌ى DataReceived حل شدنى هست.

صبا صبوحى

BeyondMicrosoft
سه شنبه 13 شهریور 1386, 21:41 عصر
با سلام
به دلیل اینکه SerialPort از Thread جداگانه استفاده می کنه و Thread ها از پشته جداگانه استفاده می کنند و به شی های هم دیگر دسترسی ندارند دستور Invoke ایجاد شده است.
برای استفاده می توانید کد زیر را در خارج از یک کلاس بنویسید (چون خود Delegate ها نوعی کلاس هستند):


Delegate void RecEventhandler();

بعد در داخل رویداد Recive باید به شکل زیر عمل نمایید :


this.Invoke(new RecEventhandler(Call_Method));

سپس متدی با شکل زیر ایجاد نموده و کد مربوطه را در آن ایجاد نمایید :


void Call_Method()
{
دستورات
}

amirsajjadi
چهارشنبه 01 خرداد 1387, 13:35 عصر
با سلام
شما به جای Invoke از این کد استفاده کنید (در رویداد Form_Load)


Control.CheckForIllegalCrossThreadCalls = False

اگر جواب نداد به این صورت Invoke ساخته شده رو در رویداد Form_Close نابود کنید


TextBox1.EndInvoke