نمایش نتایج 1 تا 15 از 15

نام تاپیک: background worker

  1. #1

    background worker

    من به backgroundworker مشکل زیر را دارم:

    توی رویداد BackgroundWorker1.DoWork به یک combobox دسترسی پیدا می کنم که خطای زیر را می ده:

    Cross-thread operation not valid: Control 'vilageComboBox' accessed from a thread other than the thread it was created on

    چه کنم؟

  2. #2
    محروم شده
    تاریخ عضویت
    اردیبهشت 1386
    پست
    193
    کد زیر را تو رویداد لود فرم اصلیت یا توی constructor فرم اصلیت بعد از initializeComponent() بذار



    Control.CheckForIllegalCrossThreadCalls = false;


    موفق باشید
    مهدی کیانی

  3. #3
    یه مشکل جدید:
    می خواهیم مثلا وقتی دکمه ای کلیک شد رویداد backgroundworker.dowork از اول فراخوانی شود. اگر همین طور runworkerasync را اجرا کنیم که خطا می دهد چون می

    گو ید در این نخ الان یک کار در حال انجام است. تا اینجا تعجبی ندارد ولی وقتی cancelasync را هم اجرا می کنیم باز وقتی به خط بعدی یعنی اجرای runworkerasync می رسد همان خطا

    را می ده که نخ داره اجرا میشه. مگه ما cancel نکردیمش .

  4. #4
    نقل قول نوشته شده توسط HAIdle مشاهده تاپیک
    من به backgroundworker مشکل زیر را دارم:

    توی رویداد BackgroundWorker1.DoWork به یک combobox دسترسی پیدا می کنم که خطای زیر را می ده:

    Cross-thread operation not valid: Control 'vilageComboBox' accessed from a thread other than the thread it was created on

    چه کنم؟

    سلام
    یکی از دوستان پیشنهاد استفاده از CheckForIllegalCrossThreadCalls رو دادن، که من 100% باهاش مخالفم. راه درست این هستش که از متود ReportProgress استفاده کنید، به این ترتیب Event ای Fire میشه که در کانتکست Main Thread شما هستش و شما می تونید بدون نگرانی به کنترلهای صفحه دست پیدا کنید.

    در مورد CancelAsync هم باید عرض کنم که اسم متود روشه! Asynchronous کار میکنه. یعنی اینکه خارج شدن از این متود به معنی Cancel شدن BW نیست، بلکه به معنی شروع عمل Cancel شدن هستش. این وظیفه شما هستش که با Synchronization Object ها از اتمام کار BW، بعد ازCancelAsync اطمینان پیدا کنید.

  5. #5
    کاربر دائمی آواتار __H2__
    تاریخ عضویت
    اسفند 1385
    محل زندگی
    یک جایی بین Framework و نارمک!
    پست
    1,059
    سلام
    من هم با نظرات کاربر mehdi6755 موافق هستم!
    برای ارسال مقادیر به شاخه، بهتر است قبل از شروع شاخه مقادیر را با کمک (RunWorkerAsync(Object argument ارسال کنید و در داخل رویداد مقادیر را از e.Argument تحویل بگیرید.

    و برای فرستادن مقادیر از رشته به برنامه اصلی هم میتوانید از متد ReportProgress و رویداد ProgressChanged و یا e.Result استفاده کنید.

    برای چک کردن وضعیت و شروع مجدد هم میتوانید از خصوصیات CancellationPending و IsBusy کمک بگیرید.
    البته راه های دیگری هم دارد، ولی معمولاً با همین روشهای رسمی تر و قانونی تر مشکل برطرف میشود! و نیز این روشها پرسرعت هم هستند.

    البته از کاربر kiani.mehdi هم تشکر میکنم، چون من اصلاً آن مشخصه را ندیده بودم!!!!!؟؟؟؟؟!!!! ولی به نظرم جالب نیست!

  6. #6

    نقل قول: background worker

    سلام
    اینجوری یه مقدار میشه از نوی Object فرستاد ...
    من یه تابع توی برنامم دارم که میخواستم با استفاده از backgrondworler اجراش کنم و این تابع تودرتو هست که 3 تا مقدار متفاوت در هربار اجرا میگیره چجوری میشه اولا چند مقدار نوع از مقادیر رو ارسال کرد و مشکل تو در تو بودنشو حل کرد !؟

  7. #7
    کاربر دائمی آواتار __H2__
    تاریخ عضویت
    اسفند 1385
    محل زندگی
    یک جایی بین Framework و نارمک!
    پست
    1,059

    نقل قول: background worker

    سلام
    از تاخیر جواب عضر خواهی میکنم.
    چجوری میشه اولا چند مقدار نوع از مقادیر رو ارسال کرد
    مساله مهمی نیست! کافی است آرایه کنید

    مثلاً:

    object one = new object[]{1,2,3};

    //...


    object[] arr = (object[])one;
    object obj1 = arr[0];
    object obj2 = arr[1];
    object obj3 = arr[2];


    مشکل تو در تو بودنشو حل کرد
    درست متوجه نشدم؟
    رویداد DoWork که آغاز شود میتوانید هر تابعی را فراخوانی کنید، مهم نیست، همه با ریسمان جدید انجام خواهد ...

    public void DoWork(...)
    {
    Func1();
    Func2();
    Func3();
    }

    private Func1()
    {
    Func5();
    Func6();
    }

    ...


    مجدد از تاخیر عضر خواهی میکنم و موفق باشید.

  8. #8

    نقل قول: background worker

    ممنون از کمکتون اما اگه ما نخوایم که مقدار رو از نوع Obj ارسال کنیم چی ؟!!
    یک مقدار این موضوع گنگه چون اگه همه مقادیر ارسالی رو بخوایم با تبدیل به این صورت ارسال کنیم کارایی و ... برنامه میاد پایین ... مثلا من میخوام یه String و یک TreeNode ارسال کنم ولی اونجوری نمیشه این کارو کرد ؟! اگه یک مقدار بیشتر توضیح بدین ممنون میشم ...
    من مشکل همه رو توی این قضیه دارم توی تاپیک vb.net حل میکنم ولی خودم هنوز باهاش مشکل دارم !

  9. #9

    نقل قول: background worker

    درست متوجه نشدم؟
    رویداد DoWork که آغاز شود میتوانید هر تابعی را فراخوانی کنید، مهم نیست، همه با ریسمان جدید انجام خواهد ...
    یه تابع هست که مثلا 2 مقدار میگیره و اجرا میشه و n دفعه خودش رو با 2 مقدار جدید راه اندازی میکنه(از توی کد های خودش .. مثله یه حلقه) ... DoWork یکبار اجرا میشه و نمیشه مثل همچین تابعی ازش استفاده کرد .... ؟

  10. #10
    کاربر دائمی آواتار __H2__
    تاریخ عضویت
    اسفند 1385
    محل زندگی
    یک جایی بین Framework و نارمک!
    پست
    1,059

    نقل قول: background worker

    سلام
    ... توی تاپیک vb.net ...
    الآن کد VB میخواهید یا #c?

    اما اگه ما نخوایم که مقدار رو از نوع Obj ارسال کنیم چی ؟!!
    یک مقدار این موضوع گنگه چون اگه همه مقادیر ارسالی رو بخوایم با تبدیل به این صورت ارسال کنیم کارایی و ... برنامه میاد پایین ... مثلا من میخوام یه String و یک TreeNode ارسال کنم ولی اونجوری نمیشه این کارو کرد ؟! اگه یک مقدار بیشتر توضیح بدین ممنون میشم ...
    این مسئله خیلی مهم و پیچیده ای نیست.
    اولاً که شما راه های مختلفی دارید (که در پایین مثال میزنم)
    بعد هم سرعت و بازدهی به سه دلیل عمده کاهش نمی یابد ...
    1) فرمان قالب ریزی مستقیم سرعت بسیار زیادی دارد (DirectCast)
    2) نصف این تبدیل فوق العاده سریع در ریسمان جدید انجام میشود که قرار است کار سنگینی انجام دهد ...
    (مثل جمع عدد 1 با عدد 1000 می ماند که عملاً بی تاثیر است)

    3) برنامه شما در حلقه کار نمیکند و این عمل فقط و فقط یکبار انجام میشود.
    اصولاً هر کجا کاهش سرعت داریم، همانجا نوعی حلقه پیدا/پنهان داریم که کاری را مدام و مدام انجام میدهد.

    روش اول:

    //C#‎.Net
    public void AsyncStart()
    {
    int param1 = 14;
    string param2 = "14";
    DateTime param3 = DateTime.UtcNow;

    System.Threading.Thread thread = new System.Threading.Thread(this.Start);
    thread.IsBackground = true;
    thread.Start(new object[] { param1, param2, param3 });
    }

    private void Start(object obj)
    {
    object[] arr = (object[])obj;
    int param1 = (int)arr(0);
    string param2 = (string)arr(1);
    DateTime param3 = (DateTime)arr(2);
    //...
    }


    'VB.Net
    Public Sub AsyncStart()
    Dim param1 As Integer = 14
    Dim param2 As String = "14"
    Dim param3 As Date = Date.UtcNow

    Dim thread As New System.Threading.Thread(AddressOf Me.Start)
    thread.IsBackground = True
    thread.Start(New Object() {param1, param2, param3})
    End Sub

    Private Sub Start(ByVal obj As Object)
    Dim arr() As Object = DirectCast(obj, Object())
    Dim param1 As Integer = DirectCast(arr(0), Integer)
    Dim param2 As String = DirectCast(arr(1), String)
    Dim param3 As Date = DirectCast(arr(2), Date)
    '...
    End Sub


    روش دوم:

    //C#‎.Net
    private struct ParamList
    {
    public int param1;
    public string param2;
    public DateTime param3;
    }

    public void AsyncStart()
    {
    ParamList param = new ParamList();
    param.param1 = 14;
    param.param2 = "14";
    param.param3 = DateTime.UtcNow;

    System.Threading.Thread thread = new System.Threading.Thread(this.Start);
    thread.IsBackground = true;
    thread.Start(param);
    }

    private void Start(object obj)
    {
    //...
    ParamList param = (ParamList)obj;
    }


    'VB.Net
    Private Structure ParamList
    Public param1 As Integer
    Public param2 As String
    Public param3 As Date
    End Structure

    Public Sub AsyncStart()
    Dim param As New ParamList
    param.param1 = 14
    param.param2 = "14"
    param.param3 = Date.UtcNow

    Dim thread As New System.Threading.Thread(AddressOf Me.Start)
    thread.IsBackground = True
    thread.Start(param)
    End Sub

    Private Sub Start(ByVal obj As Object)
    Dim param As ParamList = DirectCast(obj, ParamList)
    '...
    End Sub


    روش سوم:

    //C#‎.Net
    private sealed class WapperClass
    {
    public int param1;
    public string param2;
    public System.DateTime param3;

    public void AsyncStart()
    {
    System.Threading.Thread thread = new System.Threading.Thread(this.Start);
    thread.IsBackground = true;
    thread.Start(param);
    }

    private void Start()
    {
    //...
    }

    }

    'VB.Net
    Private NotInheritable Class WapperClass
    Public param1 As Integer
    Public param2 As String
    Public param3 As Date

    Public Sub AsyncStart()
    Dim thread As New System.Threading.Thread(AddressOf Me.Start)
    thread.IsBackground = True
    thread.Start(param)
    End Sub

    Private Sub Start()
    '...
    End Sub

    End Class


    یه تابع هست که مثلا 2 مقدار میگیره و اجرا میشه و n دفعه خودش رو با 2 مقدار جدید راه اندازی میکنه
    فرمایشاتی میفرمایید برادر، اینهاکه دیگر مسئله ندارد
    با همان روش اول هم که به نظر شما بدترین روش است به همین سادگی قابل حل است!!!

    //C#‎.Net
    private void Start(object obj)
    {
    object[] arr = (object[])obj;
    int param1 = (int)arr(0);
    string param2 = (string)arr(1);
    DateTime param3 = (DateTime)arr(2);

    this.Start(param1, param2, param3);
    }

    private void Start(int param1, string param2, DateTime param3)
    {
    //...
    if (...) this.Start(param1+1, param2+"1", param3.AddSeconds(1.0d));
    //...
    if (...) this.Start(param1+2, param2+"2", param3.AddSeconds(2.0d));
    //...
    }

    'VB.Net
    Private Sub Start(ByVal obj As Object)
    Dim arr() As Object = DirectCast(obj, Object())
    Dim param1 As Integer = DirectCast(arr(0), Integer)
    Dim param2 As String = DirectCast(arr(1), String)
    Dim param3 As Date = DirectCast(arr(2), Date)
    Me.Start(param1, param2, param3)
    End Sub

    Private Sub Start(ByVal param1 As Integer, ByVal param2 As String, ByVal param3 As Date)
    '...
    If (...) Then Me.Start(param1+1, param2+"1", param3.AddSeconds(1.0#))
    '...
    If (...) Then Me.Start(param1+2, param2+"2", param3.AddSeconds(2.0#))
    '...
    End Sub


    باز هم میبخشید که نتوانستم زودتر جواب دهم.
    موفق باشید.

  11. #11

    نقل قول: background worker

    توضیحاتتون خیلی مفید بود و از اینکه وقت گذاشتین خیلی ممنون ...
    من یه مدت پیش از روش شما استفاده کرده بودم ولی به یه ارور بر میخوردم که الان که توضیحاتتون رو مطالعه کردم فکر میکنم مشکل جای دیگه بوده احتمالا ولی در کل خیلی کمک کرد ...
    من تا چند روز آینده این قضیه رو پیگیری میکنم و اگه مشکلی بود توی کد ها با شما در میون میذارم ...
    فقط یه سوال کوچیک دیگه ...
    درون روال DoWork میشه دوباره DoWork رو اجرا کرد !؟ منظور اینه توی روال از runworkerasync استفاده کرد ! (قضیه همون تو در تو بودن هستش )
    آخرین ویرایش به وسیله Alirezanet : یک شنبه 16 اسفند 1388 در 00:29 صبح

  12. #12
    VIP آواتار gwbasic
    تاریخ عضویت
    اردیبهشت 1403
    محل زندگی
    تهران
    سن
    42
    پست
    982

    نقل قول: background worker

    اگر منظور شما را درست فهمیده باشم شما می خواهید یک متد بازگشتی را استفاده کنید
    اگه یه جستجو در مورد Backgroundworker تو MSDN بزنی یک مثالی وجود داره که دنباله فیبوناچی رو محاسبه می کنه ، فکر کنم مشکلت رو حل کنه و نیازی به فراخوانی Dowork نیست بلکه اون متد هستش که خودش رو صدا می زنه و اولین بار هم توسط Dowork صدا زده می شه

    موفق باشی

  13. #13
    کاربر دائمی آواتار __H2__
    تاریخ عضویت
    اسفند 1385
    محل زندگی
    یک جایی بین Framework و نارمک!
    پست
    1,059

    نقل قول: background worker

    سلام
    برای فراخوانی تو در تو شما به راحتی میتوانید خود متد DoWorK (همان Start من!) را فراخوانی کنید و ایرادی ندارد آن هم یک متد است، یعنی خودتان دستی با نام متد ان را صدا بزنید (...)Me.Backgroundworker_DoWork

    ولی همانطور که دوستمان gwbasic گفتند و من هم قبلاً در اخر پست 11 نوشتم شما به راحتی میتوانید یک متد دیگر با پارامترهای ورودی دلخواه (مثل دومین Start در کد آخری) داشته باشید که DoWork یا Start اصلی خودش این متد را صدا بزند و این متد پایه و اصل باشد که ورودی ها پارامتری مناسب هم داشته باشد و به هر تعداد خودش را فراخوانی کند.
    (به آخرین کد پست قبلی توجه کنید.)

    موفق باشید.

  14. #14

    نقل قول: background worker

    نقل قول نوشته شده توسط HAIdle مشاهده تاپیک
    من به backgroundworker مشکل زیر را دارم:

    توی رویداد BackgroundWorker1.DoWork به یک combobox دسترسی پیدا می کنم که خطای زیر را می ده:

    Cross-thread operation not valid: Control 'vilageComboBox' accessed from a thread other than the thread it was created on

    چه کنم؟
    نقل قول نوشته شده توسط kiani.mehdi مشاهده تاپیک
    کد زیر را تو رویداد لود فرم اصلیت یا توی constructor فرم اصلیت بعد از initializeComponent() بذار




    Control.CheckForIllegalCrossThreadCalls = false;


    موفق باشید
    مهدی کیانی

    خوب میشه یکی در مورد این مشکل و جوابش یه توضیح بده ... از نظر کارایی نمیگم درست کار میکنه ولی دقیقا این کد چیکار میکنه ؟!!


    Control.CheckForIllegalCrossThreadCalls = false;

    استفاده از این چه مشکلاتی داره !

    یکی از بچه ها هم یه سوال کرد که نتونستم جوابشو بدم گفتم شما شاید بتونین ! :

    اولا
    چرا کدی که بدون استفاده از BackGroundWorker مثلا طی 10 ثانیه کارش تموم میشه با استفاده از این کنترل در حدود 1 دقیقه طول میکشه !؟ (منظور که خیلی بیشتر طول میکشه ؟! )
    چیکار میشه کرد سرعت کار هم بالا بره ؟! مثل کارایی ؟! امکانش هست ! ؟
    من که نتونستم جواب بدم شما کمک کنین!

  15. #15
    کاربر دائمی آواتار __H2__
    تاریخ عضویت
    اسفند 1385
    محل زندگی
    یک جایی بین Framework و نارمک!
    پست
    1,059

    نقل قول: background worker

    سلام
    از نظر کارایی نمیگم[،] درست کار میکنهCOLOR="Olive"][،][/COLOR]
    نمیدانم منظورتان آن بود که درست کار میکند یا نه؟! بستگی به ویرگولی دارد که نگذاشتید !
    ولی بدانید که همیشه درست کار نمیکند! و این راهش نیست.

    دات نت به صورت داخلی ریسمانی را که فرامین کنترلرها را اجرا میکند چک میکند تا مطمئن شود همان ریسمان اصلی است (ریسمانی که صف پیام های ویندوز را در دست دارد) و گرنه خطا میدهد.

    خصیصه CheckForIllegalCrossThreadCalls این بررسی و تست توسط دات نت را فعال و غیر فعال میکند.
    (که پیشنهاد میکنم دستش نزنید و بگذارید فعال باشد.)

    را حل اصلی و صحیح کامل استفاده از خصیصه InvokeRequired به همراه متد Invoke یا BeginInvoke است.
    بدیهی است که اگر همین سایت برنامه نویس را با این کلمات جستجو کنید مطالب خوبی خواهید یافت.

    من قبلاً در تاپیک سایت دیگری این موارد را تشریح کردم...
    این کد صحیح نمادین:

    private delegate void TextReportDelegate(string value);
    //__________________________________________________ ______________________

    public void TextReport(string text)
    {
    if (this.InvokeRequired)
    {
    //[run in new thread]
    this.BeginInvoke(new TextReportDelegate(this.TextReport), text); //switch and pass to main thread.
    return;
    }
    //---
    //[run in main thread]
    //...
    this.TextBox1.Text = text;
    //...
    }
    //__________________________________________________ ______________________



    //Start ... [run in main thread]
    private void btnStart_Click(object sender, EventArgs e)
    {
    if (this.backgroundWorker1.IsBusy) return;
    //-----
    this.btnStart.Enabled = false;
    this.TextReport("Start ...");
    object arg;
    //...
    //...arg = ...
    //...
    //-----
    this.backgroundWorker1.RunWorkerAsync(arg); //start new thread.
    }
    //__________________________________________________ ______________________

    //Work ... [run in new thread]
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
    object arg = e.Argument;
    object result;
    //-----
    //...
    //...while(...)
    //...
    //...Function1(...)
    //...
    this.TextReport("Progress ...");
    //...
    //...Function2(...)
    //...
    //...result = ...
    //...
    //-----
    e.Result = result;
    }
    //__________________________________________________ ______________________

    //End. [run in main thread]
    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
    object result = e.Result;
    //-----
    //...
    this.TextReport("Completed.");
    //...
    //...MsgBox ...
    //...
    //-----
    this.btnStart.Enabled = true;
    }
    //__________________________________________________ ______________________

    این هم توضیحاتش:
    http://forum.p30world.com/showthread...30#post4690830

    من که نتونستم جواب بدم شما کمک کنین!
    در شرایط عادی و بدون تغییر تنظیم ریسمان سرعت اجرا نباشد فرقی کند.
    گمانم کد این دوست شما مشکل دارد.
    کسی در تالار دیگری کندی سرعت شکایت داشت، کدش را دیدم رفتم تو هنگ!!!
    حالا شما میفرمائید فقط در ریسمان جدید مشکل دارد.
    اگر تفاوت کم باشد که هیچ وگرنه باید کد باشد تا بتوان مشکل را تشخیص داد.

    موفق باشید.

تاپیک های مشابه

  1. ASP.NET Worker Process
    نوشته شده توسط Gladiator در بخش برنامه نویسی در Delphi Prism
    پاسخ: 11
    آخرین پست: شنبه 13 تیر 1388, 10:45 صبح
  2. Unable to start debugging on the web server . unable to attach to ASP.NET worker process (typically
    نوشته شده توسط alirezaict در بخش برنامه نویسی مبتنی بر Microsoft .Net Framework
    پاسخ: 0
    آخرین پست: یک شنبه 27 آبان 1386, 21:25 عصر
  3. کار با background worker در VB.net 2005
    نوشته شده توسط محمد زارع در بخش VB.NET
    پاسخ: 3
    آخرین پست: دوشنبه 15 مرداد 1386, 16:39 عصر
  4. اجرای برنامه در background
    نوشته شده توسط Mohammadi_F در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 5
    آخرین پست: یک شنبه 06 اسفند 1385, 07:43 صبح
  5. background
    نوشته شده توسط benyamin_pc در بخش C#‎‎
    پاسخ: 1
    آخرین پست: جمعه 15 دی 1385, 11:54 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •