ব্যাকগ্রাউন্ড কর্মীর পক্ষে যুক্তি পাঠাচ্ছেন?


147

ধরা যাক আমি কোনও ব্যাকগ্রাউন্ড কর্মীকে একটি ইনট প্যারামিটার পাঠাতে চাই, এটি কীভাবে সম্পন্ন করা যায়?

private void worker_DoWork(object sender, DoWorkEventArgs e) {

}

আমি জানি এটি কখন কর্মী un

উত্তর:


235

আপনি এটি এভাবে শুরু করুন:

int value = 123;
bgw1.RunWorkerAsync(argument: value);  // the int will be boxed

এবং তারপর

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{
   int value = (int) e.Argument;   // the 'argument' parameter resurfaces here

   ...

   // and to transport a result back to the main thread
   double result = 0.1 * value;
   e.Result = result;
}


// the Completed handler should follow this pattern 
// for Error and (optionally) Cancellation handling
private void worker_Completed(object sender, RunWorkerCompletedEventArgs e) 
{
  // check error, check cancel, then use result
  if (e.Error != null)
  {
     // handle the error
  }
  else if (e.Cancelled)
  {
     // handle cancellation
  }
  else
  {          
      double result = (double) e.Result;
      // use it on the UI thread
  }
  // general cleanup code, runs when there was an error or not.
}

38
আমি কীভাবে দুটি যুক্তি করতে পারি?
sooprise

3
বা আমি কি একাধিক যুক্তি পূর্ণ একটি বস্তু পাঠাতে?
26:48

23
@soo: একটি সহায়ক শ্রেণি বা একটি Tuple<A,B>(সি # 4 +) ব্যবহার করুন (সম্পাদনা: হ্যাঁ, সমস্ত কিছু প্যাক করার জন্য কোনও বস্তু ব্যবহার করুন example উদাহরণস্বরূপ ডো ওয়ার্কএন্টেন্টআরগস দেখুন)।
হেন্ক হলটারম্যান

তবে আপনি ফলাফলটির ইউআইকে কীভাবে জানান?
রায়রে

1
@ রায়েরে:, label1.Text = e.Result.ToString();যে কোনও জায়গায় আমি সেটিকে নিরাপদ হিসাবে চিহ্নিত করেছি।
হেন্ক হলটারম্যান

101

যদিও এটি একটি ইতিমধ্যে উত্তর দেওয়া প্রশ্ন, আমি অন্য একটি বিকল্পটি ছেড়ে যেতে চাই যে আইএমওটি পড়তে অনেক সহজ:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, e) => WorkerDoWork(value, text);
worker.RunWorkerAsync();

এবং হ্যান্ডলার পদ্ধতিতে:

private void WorkerDoWork(int value, string text) {
    ...
}

12
আমি জানি না আইএমও বলতে কী বোঝায়, আমি ভেবেছিলাম এটি একটি সি # জিনিস thing আমি "সি # আইএমও" গুগল
বৈদ্যুতিক

কিভাবে প্রায় 3 পরামিতি?
ইউকিসাকুরা

আমি ২০১২ সাল থেকে নেট নেট নিয়ে খেলছি না, তবে যদি ভুল না হয় তবে আপনি যে প্যারামিটারগুলি ... => WorkerDoWork(a, b, c);মেথডের স্বাক্ষরের সাথে মেলে ততক্ষণ আপনি যুক্ত করতে পারেন ... WorkerDoWork(int a, string b, string c) {...
dcarneiro

1
মনে রাখবেন আপনি যদি এটি ব্যবহার করেন (যেমন আমি করার চেষ্টা করেছি), আপনাকে প্রতিবার একটি নতুন ব্যাকগ্রাউন্ড ওয়ার্কার তৈরি করতে হবে (উদাহরণস্বরূপ আপনি করেছিলেন)। অন্যথায় আপনার মত একটি সমস্যা হবে যেমন আমি করেছি। আমার ব্যাকগ্রাউন্ডকর্মার আগের রানগুলি পুনরাবৃত্তি করতে থাকবে। একবার চালালে ঠিক হয়ে গেল। 2 বার এটি সর্বশেষ রান এবং বর্তমান রান পুনরাবৃত্তি। তৃতীয় রান শেষ দুটি এবং বর্তমান পুনরাবৃত্তি হবে। ইত্যাদি
বিসিয়া

তবে কীভাবে মানটি রানওকারকারসাইকটিতে পাস হবে?
কোডিবাগস্টাইন

47

আপনি এই জাতীয় একাধিক যুক্তি পাস করতে পারেন।

List<object> arguments = new List<object>();
                    arguments.Add(argument 1);
                    arguments.Add(argument 1);
                    arguments.Add(argument n);


                    backgroundWorker2.RunWorkerAsync(arguments);

private void worker_DoWork(object sender, DoWorkEventArgs e) {

  List<object> genericlist = e.Argument as List<object>;
  extract your multiple arguments from this list and cast them and use them. 

}

@ মিস রেসক্লুসিভ "জেনেরিকলিস্ট" আইটেমগুলি কাস্ট করুন, যাক, যাক "আর্গুমেন্ট 1" টাইপ ইন্ট আর্গুমেন্ট 1 = (ইনট) জেনারিকলিস্ট [0]
আলী

1
এটি রক্ষণাবেক্ষণের দিক থেকে একটি খারাপ ধারণা। আপনার তালিকার উপরে <কথায় কথায় কংক্রিটের ধরণগুলি ব্যবহার করা উচিত কারণ কমপক্ষে আপনি কী করছেন তা অনুধাবন করতে সক্ষম হবেন (নীচে আমার উত্তরের উদাহরণ দেখুন)
ডেনিস

আমি সম্ভবত Tupleজেনেরিক বস্তুর তালিকার চেয়ে একটি (বা একটি বিশেষায়িত শ্রেণি) পছন্দ করব
জেমস এস

9

আপনি DoWorkEventArgs.Argumentসম্পত্তি ব্যবহার করতে পারেন ।

মাইক্রোসফ্টের সাইটে একটি সম্পূর্ণ উদাহরণ (এমনকি কোনও আন্তঃ যুক্তি ব্যবহার করে) পাওয়া যাবে:


6

পরীক্ষা করে দেখুন DoWorkEventArgs.Argument প্রপার্টি :

...
backgroundWorker1.RunWorkerAsync(yourInt);
...

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // Do not access the form's BackgroundWorker reference directly.
    // Instead, use the reference provided by the sender parameter.
    BackgroundWorker bw = sender as BackgroundWorker;

    // Extract the argument.
    int arg = (int)e.Argument;

    // Start the time-consuming operation.
    e.Result = TimeConsumingOperation(bw, arg);

    // If the operation was canceled by the user, 
    // set the DoWorkEventArgs.Cancel property to true.
    if (bw.CancellationPending)
    {
        e.Cancel = true;
    }
}

5

আপনি যদি একাধিক ধরণের আর্গুমেন্ট পাস করতে চান তবে এটি চেষ্টা করে দেখতে পারেন, প্রথমে সেগুলি সমস্ত প্রকারের অবজেক্টের অ্যারে যুক্ত করুন এবং সেই বস্তুকে রানওয়ারকারএেন্সেন্স () এ পাস করুন এখানে একটি উদাহরণ রয়েছে:

   some_Method(){
   List<string> excludeList = new List<string>(); // list of strings
   string newPath ="some path";  // normal string
   Object[] args = {newPath,excludeList };
            backgroundAnalyzer.RunWorkerAsync(args);
      }

ব্যাকগ্রাউন্ড কর্মীদের এখন ডো ওয়ার্ক পদ্ধতিতে

backgroundAnalyzer_DoWork(object sender, DoWorkEventArgs e)
      {
        backgroundAnalyzer.ReportProgress(50);
        Object[] arg = e.Argument as Object[];
        string path= (string)arg[0];
        List<string> lst = (List<string>) arg[1];
        .......
        // do something......
        //.....
       }

2
+1 যুক্তিগুলি এই পদ্ধতিতে প্রেরণ করা পুনরাবৃত্তিগুলি এড়াতে প্রতিটি রান একটি নতুন ব্যাকগ্রাউন্ডকর্মার শুরু করাও এড়িয়ে যায়। (কমপক্ষে আমার অ্যাপে) এই সমস্যা সম্পর্কিত নীচে আমার মন্তব্য দেখুন। এছাড়াও stackoverflow.com/a/12231431/503621 & stackoverflow.com/questions/12507602/...
bshea


4

আপনার সর্বদা অবজেক্টের ধরণের তালিকার চেয়ে কংক্রিটের ধরণের (যৌগিক নকশার প্যাটার্ন ব্যবহার করে) একটি সমন্বিত বস্তু ব্যবহার করার চেষ্টা করা উচিত। এই জিনিসগুলির প্রত্যেকটি হেক কী তা কে মনে রাখবে? পরে আপনার কোড রক্ষণাবেক্ষণ সম্পর্কে চিন্তা করুন ... পরিবর্তে, এর মতো কিছু চেষ্টা করুন:

Public (Class or Structure) MyPerson
                public string FirstName { get; set; }
                public string LastName { get; set; }
                public string Address { get; set; }
                public int ZipCode { get; set; }
End Class

এবং তারপর:

Dim person as new MyPerson With { .FirstName = Joe”,
                                  .LastName = "Smith”,
                                  ...
                                 }
backgroundWorker1.RunWorkerAsync(person)

এবং তারপর:

private void backgroundWorker1_DoWork (object sender, DoWorkEventArgs e)
{
        MyPerson person = e.Argument as MyPerson
        string firstname = person.FirstName;
        string lastname = person.LastName;
        int zipcode = person.ZipCode;                                 
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.