Application.DoEvents()
সি # তে ব্যবহার করা যাবে ?
এই ফাংশনটি জিবিআই-কে DoEvents
কীভাবে ভিবি 6 এর মতো করে অন্যান্য অ্যাপ্লিকেশনটি ধরে ফেলতে দেয়?
Application.DoEvents()
সি # তে ব্যবহার করা যাবে ?
এই ফাংশনটি জিবিআই-কে DoEvents
কীভাবে ভিবি 6 এর মতো করে অন্যান্য অ্যাপ্লিকেশনটি ধরে ফেলতে দেয়?
উত্তর:
Hmya, DoEvents () এর চিরস্থায়ী রহস্যময়। এর বিরুদ্ধে প্রচুর পরিমাণে প্রতিক্রিয়া দেখা গেছে, তবে কেন এটি "খারাপ" তা সত্যিই কেউ ব্যাখ্যা করেনি। "স্ট্রাক্টকে রূপান্তর করবেন না" হিসাবে একই ধরণের প্রজ্ঞা। এরম, রানটাইম এবং ভাষা এতটা খারাপ হলে স্ট্রাক্টকে রূপান্তর করতে কেন সমর্থন করে? একই কারণ: আপনি যদি সঠিকভাবে না করেন তবে নিজেকে পায়ে গুলি করুন। সহজে। এবং এটি সঠিকভাবে করার জন্য এটি ঠিক কী করে তা জেনে রাখা দরকার , যা ডওভেন্টসের ক্ষেত্রে () স্পষ্টভাবে আঁকানো সহজ নয়।
সরাসরি ব্যাট বন্ধ: প্রায় কোনও উইন্ডোজ ফর্ম প্রোগ্রামে ডওভেন্টস () তে কল রয়েছে। এটি চালাকভাবে ছদ্মবেশযুক্ত, তবে আলাদা নামের সাথে: শোডায়ালগ ()। এটি ডোইভেন্টস () যা অ্যাপ্লিকেশনের বাকী উইন্ডোজ হিমায়িত করে একটি ডায়ালগকে মডেল হতে দেয়।
বেশিরভাগ প্রোগ্রামাররা নিজের মডেল লুপটি লেখার সময় তাদের ব্যবহারকারীর ইন্টারফেসকে হিমায়িত থেকে বিরত রাখতে ডওভেন্টস ব্যবহার করতে চান। এটি অবশ্যই তা করে; এটি উইন্ডোজ বার্তা প্রেরণ করে এবং যে কোনও পেইন্টের অনুরোধ বিতরণ করে। সমস্যাটি তবে এটি নির্বাচনী নয় lective এটি কেবল পেইন্ট বার্তা প্রেরণ করে না, পাশাপাশি সমস্ত কিছু সরবরাহ করে।
এবং বিজ্ঞপ্তিগুলির একটি সেট রয়েছে যা সমস্যার সৃষ্টি করে। তারা মনিটরের সামনে প্রায় 3 ফুট থেকে আসে। ব্যবহারকারী উদাহরণস্বরূপ মূল উইন্ডোটি বন্ধ করতে পারত যখন ডওভেন্টস () কল করে এমন লুপ চলছিল। এটি কাজ করে, ইউজার ইন্টারফেস চলে গেছে। তবে আপনার কোডটি থামেনি, এটি এখনও লুপটি কার্যকর করছে। এটা খারাপ. খুব খুব খারাপ.
আরও রয়েছে: ব্যবহারকারী একই মেনু আইটেম বা বোতামটি ক্লিক করতে পারে যার ফলে একই লুপটি শুরু হতে পারে। এখন আপনি দুটি নেস্টড লুপগুলি ডু এভেন্টস () সম্পাদন করছেন, পূর্ববর্তী লুপটি স্থগিত করা হয়েছে এবং নতুন লুপটি শুরু থেকে শুরু হচ্ছে। এটি কাজ করতে পারে, তবে ছেলেদের মতভেদগুলি পাতলা। বিশেষত যখন নেস্টেড লুপ শেষ হয়ে যায় এবং স্থগিত হওয়াটি পুনরায় শুরু হয়, ইতিমধ্যে সম্পন্ন একটি কাজ শেষ করার চেষ্টা করে। যদি এটি একটি ব্যতিক্রম নিয়ে বোমা না দেয় তবে অবশ্যই ডেটাগুলি সমস্ত নরকে স্ক্র্যাম্ব করে।
শোডায়ালগ () এ ফিরে যান। এটি DoEvents () কার্যকর করে, তবে মনে রাখবেন যে এটি অন্য কিছু করে। এটি ডায়ালগ বাদে অ্যাপ্লিকেশনটির সমস্ত উইন্ডো অক্ষম করে । এখন যে 3-ফুট সমস্যা সমাধান হয়েছে, ব্যবহারকারী যুক্তিটি গণ্ডগোলের জন্য কিছুই করতে পারবেন না। উইন্ডো এবং ক্লাস-দ্য জব-উভয়ই আবার ব্যর্থতার মোডগুলি সমাধান করা হয়েছে। অথবা এটি অন্য উপায়ে বলতে গেলে, ব্যবহারকারীর পক্ষে আপনার প্রোগ্রামকে আলাদা কোডে রান কোড করার কোনও উপায় নেই। এটি পূর্বাভাসের সাথে কার্যকর করা হবে, ঠিক যেমনটি আপনি যখন নিজের কোডটি পরীক্ষা করেছিলেন। এটি সংলাপগুলি অত্যন্ত বিরক্তিকর করে তোলে; ডায়লগটি সক্রিয় থাকা এবং অন্য উইন্ডো থেকে কোনও কিছু অনুলিপি করতে এবং পেস্ট করতে সক্ষম না হওয়া কে ঘৃণা করে না? তবে এটাই দাম।
আপনার কোডটিতে নিরাপদে DoEvents ব্যবহার করতে যা লাগে। আপনার সমস্ত ফর্মের সক্ষম সম্পত্তিটিকে মিথ্যা হিসাবে সেট করা সমস্যাগুলি এড়ানোর একটি দ্রুত এবং কার্যকর উপায়। অবশ্যই, কোনও প্রোগ্রামার আসলে এটি করা পছন্দ করে না। এবং না। যে কারণে আপনার DoEvents () ব্যবহার করা উচিত নয়। আপনার থ্রেড ব্যবহার করা উচিত। যদিও তারা আপনাকে রঙিন এবং অনিচ্ছাকৃত উপায়ে আপনার পায়ে গুলি করার জন্য একটি সম্পূর্ণ অস্ত্রাগার দেয় hand তবে এই সুবিধাটি দিয়ে যে আপনি কেবল নিজের পা ছুঁড়েছেন; এটি (সাধারণত) ব্যবহারকারীকে তার গুলি করতে দেয় না।
C # এবং VB.NET এর পরবর্তী সংস্করণগুলি নতুন প্রতীক্ষা এবং অ্যাসিঙ্ক কীওয়ার্ড সহ একটি আলাদা বন্দুক সরবরাহ করবে। DoEvents ও থ্রেড কিন্তু WinRT এর API- নকশা বড় অংশ যে সৃষ্ট কষ্ট দ্বারা ছোট অংশ অনুপ্রাণিত প্রয়োজন আপনি আপনার ইউআই আপডেট রাখতে সময় একটি অ্যাসিঙ্ক্রোনাস অপারেশন স্থান গ্রহণ করা হয়। একটি ফাইল থেকে পড়া মত।
BackgroundWorker
অংশটি আপনার জন্য থ্রেড পরিচালনা করে, বেশিরভাগ বর্ণা outcome্য পরিণতি এড়িয়ে চলে - এবং এটির জন্য রক্তপাতের প্রান্ত সি # ভাষার সংস্করণ প্রয়োজন হয় না।
এটি হতে পারে তবে এটি একটি হ্যাক।
দেখুন কি দুর্যোগগুলি মন্দ? ।
দেবদেব উল্লেখ করেছেন যে এমএসডিএন পৃষ্ঠা থেকে সরাসরি :
সমস্ত ওয়েটিং উইন্ডো বার্তাগুলি প্রক্রিয়া করার সময় এই পদ্ধতিতে কল করার ফলে বর্তমান থ্রেড স্থগিত হয়ে যায়। যদি কোনও বার্তা কোনও ইভেন্টকে ট্রিগার করার কারণ হয়ে থাকে, তবে আপনার অ্যাপ্লিকেশন কোডের অন্যান্য ক্ষেত্রগুলি কার্যকর করতে পারে। এটি আপনার অ্যাপ্লিকেশনটিকে অপ্রত্যাশিত আচরণগুলি প্রদর্শন করতে পারে যা ডিবাগ করা কঠিন। আপনি যদি দীর্ঘ সময় নেয় এমন ক্রিয়াকলাপ বা গণনা সম্পাদন করেন তবে নতুন থ্রেডে এই ক্রিয়াকলাপগুলি সম্পাদন করা প্রায়শই ভাল। অ্যাসিনক্রোনাস প্রোগ্রামিং সম্পর্কে আরও তথ্যের জন্য, অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং ওভারভিউ দেখুন।
তাই মাইক্রোসফ্ট এর ব্যবহারের বিরুদ্ধে সাবধান করে দেয়।
এছাড়াও, আমি এটিকে হ্যাক হিসাবে বিবেচনা করি কারণ এর আচরণটি অনুমানযোগ্য এবং পার্শ্বপ্রতিক্রিয়াযুক্ত প্রবণ (এটি একটি নতুন থ্রেড কাটানোর পরিবর্তে বা ব্যাকগ্রাউন্ড কর্মী ব্যবহারের পরিবর্তে ডওভেন্টস ব্যবহার করার চেষ্টা করার অভিজ্ঞতা থেকে আসে)।
এখানে কোনও মেশিমো নেই - এটি যদি একটি শক্তিশালী সমাধান হিসাবে কাজ করে তবে আমি এটির সব শেষ হয়ে যাব। যাইহোক, .NET এ DoEvents ব্যবহার করার চেষ্টা করায় আমার ব্যথা ছাড়া আর কিছুই হয়নি।
BackgroundWorker
"সঠিক" উপায়টিকে সহজতর করতে সহায়তা করেছিল।
হ্যাঁ, সিস্টেমে অ্যাপ্লিকেশন শ্রেণিতে একটি স্ট্যাটিক ডোইভেন্টস পদ্ধতি রয়েছে। উইন্ডোস Forফর্মস নামস্থান ace UI থ্রেডে দীর্ঘ-চলমান কার্য সম্পাদন করার সময় System.Windows. Forms.Application.DoEvents () ইউআই থ্রেডের কাতারে অপেক্ষা করা বার্তাগুলি প্রক্রিয়া করতে ব্যবহার করা যেতে পারে। এটি দীর্ঘস্থায়ী কাজ চলাকালীন ইউআইকে আরও প্রতিক্রিয়াশীল বলে মনে হচ্ছে এবং "লকআপ" না করার সুবিধা রয়েছে। তবে এটি প্রায় সর্বদা জিনিস করার সর্বোত্তম উপায় নয়। মাইক্রোসফ্ট ডোইভেন্টসকে ডেকে জানিয়েছে "... সমস্ত অপেক্ষার উইন্ডো বার্তাগুলি প্রক্রিয়া করার সময় বর্তমান থ্রেড স্থগিত করে দেয়।" যদি কোনও ইভেন্ট ট্রিগার করা হয় তবে অপ্রত্যাশিত ও বিরতিযুক্ত বাগের সম্ভাবনা রয়েছে যা ট্র্যাক করা কঠিন। আপনার যদি একটি বিস্তৃত কাজ থাকে তবে এটি আলাদা থ্রেডে করা আরও ভাল। পৃথক থ্রেডে দীর্ঘ কাজ চালানো তাদের ইউআইয়ের সাথে হস্তক্ষেপ না করে প্রক্রিয়াজাতকরণের অনুমতি দেয় যাতে সহজেই চলতে থাকে। লুকএখানে আরো বিস্তারিত জানার জন্য।
এখানে কীভাবে doEvents ব্যবহার করবেন তার একটি উদাহরণ রয়েছে; নোট করুন যে মাইক্রোসফ্ট এটি ব্যবহারের বিরুদ্ধে একটি সতর্কতাও সরবরাহ করে।
আমার অভিজ্ঞতা থেকে আমি। নেট এ ডোভেন্টস ব্যবহার করে দুর্দান্ত সতর্কতার পরামর্শ দেব। ডেটাগ্রিডভিউস সমন্বিত একটি ট্যাবকন্ট্রোল-এ doEvents ব্যবহার করার সময় আমি কিছু অদ্ভুত ফলাফল পেয়েছি। অন্যদিকে, আপনি যে সমস্ত বিষয় নিয়ে কাজ করছেন তা যদি একটি অগ্রগতি বারের সাথে একটি ছোট ফর্ম হয় তবে এটি ঠিক আছে।
নীচের লাইনটি হ'ল: আপনি যদি ডওভেন্টস ব্যবহার করতে চলেছেন তবে আপনার অ্যাপ্লিকেশন মোতায়েনের আগে আপনার এটি ভালভাবে পরীক্ষা করা দরকার।
হ্যাঁ.
তবে, আপনার যদি প্রয়োজন হয় তবে Application.DoEvents
এটি বেশিরভাগ খারাপ অ্যাপ্লিকেশন ডিজাইনের ইঙ্গিত। এর পরিবর্তে আপনি আলাদা থ্রেডে কিছু কাজ করতে চান?
আমি উপরের ঝেরিকোর মন্তব্য দেখেছি এবং প্রাথমিকভাবে সম্মত হয়েছি যে আপনি যদি অন্য একটি থ্রেডে দীর্ঘকালীন চলমান অ্যাসিনক্রোনাস টুকরো কোডটি অপেক্ষার জন্য অপেক্ষা করে থাকেন তবে আপনার মূল ইউআই থ্রেডটি কাটানো শেষ হলে আমি ডোইভেন্টস ব্যবহার এড়ানোর কোনও উপায় খুঁজে পাচ্ছি না। তবে ম্যাথিয়াসের উত্তর থেকে আমার ইউআই এর একটি ছোট প্যানেলের সরল রিফ্রেশটি ডওভেন্টসকে প্রতিস্থাপন করতে পারে (এবং একটি খারাপ অভ্যাস এড়াতে পারে)।
আমার মামলার আরও বিশদ ...
একটি দীর্ঘ চলমান এসকিউএল কমান্ড চলাকালীন একটি অগ্রগতি বার ধরণের স্প্ল্যাশ স্ক্রিন ( কীভাবে "লোডিং" ওভারলে প্রদর্শন করবেন ... ) আপডেট করার জন্য আমি নিম্নলিখিতটি ( এখানে প্রস্তাবিত হিসাবে ) কাজটি করছিলাম :
IAsyncResult asyncResult = sqlCmd.BeginExecuteNonQuery();
while (!asyncResult.IsCompleted) //UI thread needs to Wait for Async SQL command to return
{
System.Threading.Thread.Sleep(10);
Application.DoEvents(); //to make the UI responsive
}
খারাপ: আমার জন্য ডওএভেন্টস কল করার অর্থ হ'ল মাউস ক্লিকগুলি মাঝে মাঝে আমার স্প্ল্যাশ স্ক্রিনের পিছনে ফর্মগুলিতে গুলি চালাচ্ছিল, এমনকি যদি আমি এটি টপমস্ট তৈরি করি।
ভাল / উত্তর: আমার স্প্ল্যাশ স্ক্রিনের মাঝখানে একটি ছোট প্যানেলে সরল রিফ্রেশ কল দিয়ে ডওভেন্টস লাইনটি প্রতিস্থাপন করুন FormSplash.Panel1.Refresh()
। ইউআই সুন্দরভাবে আপডেট হয় এবং অন্যেরা যে সতর্কতা অবলম্বন করেছিল তা শেষ হয়ে গেছে Do
আমি অনেক বাণিজ্যিক অ্যাপ্লিকেশন দেখেছি, "ডোইভেন্টস-হ্যাক" ব্যবহার করে। বিশেষত যখন রেন্ডারিং খেলতে আসে, আমি প্রায়শই এটি দেখতে পাই:
while(running)
{
Render();
Application.DoEvents();
}
তারা সকলেই সেই পদ্ধতির মন্দ সম্পর্কে জানে। তবে তারা হ্যাকটি ব্যবহার করে কারণ তারা অন্য কোনও সমাধান জানেন না। টম মিলার দ্বারা একটি ব্লগ পোস্ট থেকে নেওয়া কিছু পন্থা এখানে :
- সমস্ত অঙ্কন ডাব্লুএমপেইন্টে ঘটানোর জন্য আপনার ফর্মটি সেট করুন এবং সেখানে আপনার রেন্ডারিং করুন। অনপেইন্ট পদ্ধতি শেষ হওয়ার আগে নিশ্চিত হয়ে নিন যে আপনি এটি করেছেন n এটি অনপেইন্ট পদ্ধতিটি তত্ক্ষণাত্ পুনরায় বরখাস্ত করবে।
- পি / উইন 32 এপিআইতে ডাকুন এবং পিকম্যাসেজ / ট্রান্সলেশনমেসেজ / ডিসপ্যাচমেসেজ কল করুন। (ডোভেন্টস আসলে একই রকম কিছু করে, তবে আপনি অতিরিক্ত বরাদ্দ ছাড়াই এটি করতে পারেন)।
- আপনার নিজের ফর্মগুলির শ্রেণিটি লিখুন যা ক্রিয়েটওয়াইন্ডএক্সের চারপাশে একটি ছোট মোড়ক, এবং নিজেকে বার্তা লুপের উপরে সম্পূর্ণ নিয়ন্ত্রণ দিন। -ত্যাগ করুন যে ডওভেন্টস পদ্ধতিটি আপনার পক্ষে ভাল কাজ করে এবং এর সাথে আঁকড়ে থাকেন।
Application.DoEvents
পদ্ধতির জন্য এমএসডিএন ডকুমেন্টেশন দেখুন ।
DoEvents ব্যবহারকারীর চারপাশে ক্লিক করতে বা টাইপ করতে এবং অন্যান্য ইভেন্টগুলি ট্রিগার করতে দেয় এবং পটভূমি থ্রেডগুলি আরও ভাল পদ্ধতির।
যাইহোক, এখনও এমন ঘটনা রয়েছে যেখানে আপনার সমস্যাগুলির জন্য প্রবাহিত হতে পারে যার জন্য ফ্লাশিং ইভেন্টের বার্তাগুলি প্রয়োজন। আমি এমন একটি সমস্যায় পড়েছিলাম যেখানে রিচটেক্সটবক্স নিয়ন্ত্রণ যখন স্ক্রোলটোক্রেট () পদ্ধতিটিকে উপেক্ষা করছিল তখন যখন কন্ট্রোলটিতে প্রক্রিয়া করার জন্য সারিতে থাকা বার্তা ছিল।
নিম্নলিখিত কোডগুলি DoEvents সম্পাদন করার সময় সমস্ত ব্যবহারকারীর ইনপুট অবরোধ করে:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Integrative.Desktop.Common
{
static class NativeMethods
{
#region Block input
[DllImport("user32.dll", EntryPoint = "BlockInput")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BlockInput([MarshalAs(UnmanagedType.Bool)] bool fBlockIt);
public static void HoldUser()
{
BlockInput(true);
}
public static void ReleaseUser()
{
BlockInput(false);
}
public static void DoEventsBlockingInput()
{
HoldUser();
Application.DoEvents();
ReleaseUser();
}
#endregion
}
}
গ্রাফিক্স প্রক্রিয়াজাতকরণ ব্যতীত অন্য কোনও কিছু যদি বার্তার কাতারে রাখা হয় তবে অ্যাপ্লিকেশন.ডাউনভেন্টগুলি সমস্যা তৈরি করতে পারে।
এটি অগ্রগতি বারগুলি আপডেট করার জন্য এবং মেইনফর্ম নির্মাণ এবং লোডের মতো কিছুতে ব্যবহারকারীকে অগ্রগতির বিষয়টি জানাতে কার্যকর হতে পারে, যদি এতে কিছুটা সময় লাগে।
সাম্প্রতিক একটি অ্যাপ্লিকেশন আমি করেছি, আমি লোইন স্ক্রিনে প্রতিটি লেবেল আপডেট করার জন্য DoEvents ব্যবহার করেছি প্রতিবার আমার মেইনফর্মের কনস্ট্রাক্টরে কোডের একটি ব্লক কার্যকর করা হয়েছে। এই ক্ষেত্রে, ইউআই থ্রেডটি একটি এসএমটিপি সার্ভারে ইমেল প্রেরণের সাথে দখল করা হয়েছিল যা সেন্ডএন্সিঙ্ক () কলগুলি সমর্থন করে না। আমি সম্ভবত বিগিন () এবং শেষ () পদ্ধতিগুলির সাহায্যে একটি আলাদা থ্রেড তৈরি করতে পারতাম এবং তাদের কাছ থেকে একটি প্রেরণ () বলেছিলাম, তবে সেই পদ্ধতিটি ত্রুটি-প্রবণ এবং আমি আমার অ্যাপ্লিকেশনটির মূল ফর্মটি নির্মাণের সময় ব্যতিক্রম ছুঁড়ে না পছন্দ করব।
DoEvents
উইন্ডোজ ফর্মগুলির অংশ, সি # ভাষা নয়। যেমন, এটি যে কোনও নেট ভাষা থেকে ব্যবহার করা যেতে পারে। তবে এটি কোনও। নেট ভাষা থেকে ব্যবহার করা উচিত নয় ।