কোনও প্রতিশ্রুতি-শৈলীর কাজ শুরু করে বলা যেতে পারে না। ব্যতিক্রম আসছে


108

আমি একটি সাধারণ ডাব্লুপিএফ ডেস্কটপ অ্যাপ্লিকেশন তৈরি করছি। UI এর .cs ফাইলের মতো ঠিক একটি বোতাম এবং কোড রয়েছে।

private void Button_Click_2(object sender, RoutedEventArgs e)
{
    FunctionA();
}

public void FunctionA()
{
    Task.Delay(5000).Start();
    MessageBox.Show("Waiting Complete");
}

তবে আশ্চর্যরূপে লাইনটি Task.Delay(5000).Start();একটি নিক্ষেপ করছে InvalidOperationException:

কোনও প্রতিশ্রুতি-শৈলীর কাজ শুরু করে বলা যেতে পারে না।

এটির মতো কেন কেউ সাহায্য করতে পারে?

উত্তর:


171

আপনি সেই ত্রুটিটি পাচ্ছেন কারণ Taskক্লাসটি আপনাকে দেওয়ার আগেই এই কাজটি শুরু করেছে। আপনার কেবলমাত্র Startকোনও কাজটিই তৈরি করা উচিত যা আপনি তার নির্মাণকারীকে কল করে তৈরি করেন এবং আপনি যখন এটি তৈরির সময় কাজটি শুরু না করার কোনও বাধ্যতামূলক কারণ না উপস্থিত থাকেন তখনও আপনার তা করা উচিত নয়; আপনি যদি এটি এখনই শুরু করতে চান তবে আপনার ব্যবহার করা উচিত Task.Runবা Task.Factory.StartNewউভয়ই নতুন তৈরি এবং শুরু করা উচিত Task।

সুতরাং, এখন আমরা শুধু যে বিরক্তিকর পরিত্রাণ পেতে জানি Start। আপনি আপনার কোডটি চালিয়ে যাবেন এবং বার্তাটি বাক্সটি 5 সেকেন্ড পরে নয়, এখনই দেখানো হবে, কী হবে?

ঠিক আছে, Task.Delayকেবল আপনাকে একটি কাজ দেয় যা 5 সেকেন্ডের মধ্যে শেষ হবে। এটি 5 সেকেন্ডের জন্য থ্রেডের সম্পাদন থামায় না। আপনি যা করতে চান তার কিছু কোড রয়েছে যা কার্য শেষ হওয়ার পরে কার্যকর করা হয়। এটা কি ContinueWithজন্য। প্রদত্ত টাস্কটি শেষ হওয়ার পরে এটি আপনাকে কিছু কোড চালাতে দেয়:

public void FunctionA()
{
    Task.Delay(5000)
    .ContinueWith(t => 
    {
        MessageBox.Show("Waiting Complete");
    });
}

এটি প্রত্যাশা অনুযায়ী আচরণ করবে।

awaitআরও সহজেই ধারাবাহিকতা যুক্ত করতে আমরা সি # 5.0 এর কীওয়ার্ডটিও লাভ করতে পারি:

public async Task FunctionA()
{
    await Task.Delay(5000);
    MessageBox.Show("Waiting Complete");
}

এখানে কী চলছে তার পুরো ব্যাখ্যা এই প্রশ্নের আওতার বাইরে, শেষের ফলাফলটি এমন একটি পদ্ধতি যা পূর্বের পদ্ধতির সাথে খুব অনুরূপ আচরণ করে; আপনি পদ্ধতিটি কল করার 5 সেকেন্ড পরে এটি একটি বার্তা বাক্স প্রদর্শন করবে, তবে পদ্ধতিটি নিজেই [প্রায়] সরাসরি উভয় ক্ষেত্রেই ফিরে আসবে। এটি বলেছিল, awaitখুব শক্তিশালী, এবং আমাদের এমন পদ্ধতি লিখতে দেয় যা সহজ এবং সহজবোধ্য বলে মনে হয়, তবে ContinueWithসরাসরি ব্যবহার করে লেখার পক্ষে এটি আরও কঠোর এবং মেসিয়ার হবে । এটি প্রচুর পরিমাণে বয়লারপ্লেট কোড গ্রহণ করে ত্রুটি পরিচালনার সাথে কাজ করার বিষয়টিও সহজতর করে।



-4

সার্ভি যেমন বলেছিলেন, কাজটি ইতিমধ্যে শুরু হয়ে গেছে, তাই আপনি যা করতে বাকি রেখেছেন তা ((ওয়েট ()) অপেক্ষা করুন:

private void Button_Click_2(object sender, RoutedEventArgs e)
{
    FunctionA();
}
public void FunctionA()
{
    Task.Delay(5000).Wait();
    MessageBox.Show("Waiting Complete");
}

1
Wait()কোনও টাস্কে কল করা টাস্কটির সমাধান না হওয়া অবধি বর্তমান থ্রেডটিকে ব্লক করে দেবে। আপনি যা করতে চান তা প্রায় কখনই নয়।
— জেরেমি

1
@ জেরেমি: প্রকৃতপক্ষে, আপনি যে আচরণটি উল্লেখ করেছেন সেদিকে মনোযোগ দেওয়া উচিত, তবে এই ক্ষেত্রে তার ফাংশনএ ইতিমধ্যে বর্তমান থ্রেডটি আটকাচ্ছে, তাই আমি ধরে নিয়েছিলাম যে তিনি কখন কাজটি শেষ হয়েছে তা নির্ধারণের জন্য কোনও উপায় খুঁজছেন। অপেক্ষা করুন এবং অ্যাসিঙ্ক (ভবিষ্যতের পাঠকদের জন্য) মধ্যে পার্থক্য স্পষ্ট করার জন্য দয়া করে এই লিঙ্কটি পড়ুন
— সেরগিউ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.