যখন অ্যাসিঙ্ক্রোনাস কাজগুলি একটি খারাপ ইউএক্স করে


9

আমি এমন একটি সিওএম অ্যাড-ইন লিখছি যা এটির IDE প্রসারিত করে যা এটির মারাত্মক প্রয়োজন। এতে অনেকগুলি বৈশিষ্ট্য জড়িত রয়েছে, তবে আসুন এই পোস্টের জন্য এটি 2 এ সংকুচিত করুন:

  • একটা ব্যাপার কোড এক্সপ্লোরার toolwindow যে প্রদর্শনগুলির একটি ট্রিভিউ ব্যবহারকারী নেভিগেট মডিউল এবং তাদের সদস্যদের ক্ষমতা প্রদান করে।
  • একটি আছে কোড পরিদর্শন toolwindow যে প্রদর্শনগুলির একটি datagridview ব্যবহারকারী নেভিগেট কোড বিষয় করতে দেয় এবং সেগুলি স্বয়ংক্রিয়ভাবে ঠিক যে।

উভয় সরঞ্জামের একটি "রিফ্রেশ" বোতাম রয়েছে যা একটি খোলামেলা কার্য শুরু করে যা সমস্ত খোলা প্রকল্পের সমস্ত কোডকে বিশ্লেষণ করে; কোড এক্সপ্লোরার পার্স ফলাফল ব্যবহার নির্মাণের ট্রিভিউ , এবং কোড পরিদর্শন পার্স ফলাফল ব্যবহার কোড কোনো সমস্যার সম্মুখীন এবং তার ফলাফল প্রদর্শন করে datagridview

আমি এখানে যা করার চেষ্টা করছি তা বৈশিষ্ট্যের মধ্যে পার্সিং ফলাফলগুলি ভাগ করে নেওয়া, যাতে কোড এক্সপ্লোরার রিফ্রেশ করে, তখন কোড পরিদর্শনগুলি এটি সম্পর্কে জানে এবং কোড এক্সপ্লোরার সবেমাত্র পার্সিংয়ের কাজটি পুনরায় না করেই নিজেকে রিফ্রেশ করতে পারে can ।

তাই আমি যা করেছি, আমি আমার পার্সার ক্লাসকে একটি ইভেন্ট সরবরাহকারী তৈরি করেছি যা বৈশিষ্ট্যগুলি এতে নিবন্ধিত করতে পারে:

    private void _parser_ParseCompleted(object sender, ParseCompletedEventArgs e)
    {
        Control.Invoke((MethodInvoker) delegate
        {
            Control.SolutionTree.Nodes.Clear();
            foreach (var result in e.ParseResults)
            {
                var node = new TreeNode(result.Project.Name);
                node.ImageKey = "Hourglass";
                node.SelectedImageKey = node.ImageKey;

                AddProjectNodes(result, node);
                Control.SolutionTree.Nodes.Add(node);
            }
            Control.EnableRefresh();
        });
    }

    private void _parser_ParseStarted(object sender, ParseStartedEventArgs e)
    {
        Control.Invoke((MethodInvoker) delegate
        {
            Control.EnableRefresh(false);
            Control.SolutionTree.Nodes.Clear();
            foreach (var name in e.ProjectNames)
            {
                var node = new TreeNode(name + " (parsing...)");
                node.ImageKey = "Hourglass";
                node.SelectedImageKey = node.ImageKey;

                Control.SolutionTree.Nodes.Add(node);
            }
        });
    }

এবং এটি কাজ করে। আমার যে সমস্যাটি হচ্ছে তা হ'ল ... এটি কাজ করে - মানে, কোড পরিদর্শনগুলি রিফ্রেশ হয়ে গেলে, পার্সার কোড এক্সপ্লোরারকে (এবং অন্য সবাইকে) "দোস্ত, কারও পার্সিং, আপনি এটি সম্পর্কে কিছু করতে চান? " - এবং পার্সিং সম্পূর্ণ হওয়ার পরে, পার্সার তার শ্রোতাদের বলছে "ছেলেরা, আপনার জন্য আমার নতুন বিশ্লেষণের ফলাফল রয়েছে, আপনি এটি সম্পর্কে কিছু করতে চান?"।

এটি যে সমস্যার সৃষ্টি করে তা চিত্রিত করার জন্য আপনাকে একটি উদাহরণ দিয়ে যেতে দাও:

  • ব্যবহারকারী কোড এক্সপ্লোরার এনেছে, যা ব্যবহারকারীকে বলে "ধরে থাকুন, আমি এখানে কাজ করছি"; ব্যবহারকারী আইডিইতে কাজ চালিয়ে যান, কোড এক্সপ্লোরার নিজেই আবার চিত্রিত করে, জীবন সুন্দর is
  • তারপরে ব্যবহারকারী কোড পরিদর্শনগুলি নিয়ে আসে, যা ব্যবহারকারীকে "ধরে রাখুন, আমি এখানে কাজ করছি" বলে; বিশ্লেষক কোড এক্সপ্লোরারকে "দোস্ত, কারোর পার্সিং, আপনি এটি সম্পর্কে কিছু করতে চান?" - কোড এক্সপ্লোরার ব্যবহারকারীকে বলে "ধরে থাক, আমি এখানে কাজ করছি"; ব্যবহারকারী এখনও আইডিইতে কাজ করতে পারেন, তবে কোড এক্সপ্লোরার নেভিগেট করতে পারবেন না কারণ এটি সতেজ। এবং কোডের পরিদর্শনগুলিও সম্পূর্ণ হওয়ার জন্য তিনি অপেক্ষা করছেন।
  • ব্যবহারকারী পরিদর্শন ফলাফলগুলিতে তারা সম্বোধন করতে চান এমন একটি কোড সমস্যা দেখে; তারা এতে নেভিগেট করতে ডাবল-ক্লিক করুন, কোডটিতে কোনও সমস্যা আছে তা নিশ্চিত করুন এবং "ফিক্স" বোতামটি ক্লিক করুন। মডিউলটি সংশোধন করা হয়েছিল এবং পুনরায় পার্স করা দরকার, তাই কোড পরিদর্শনগুলি এর সাথে এগিয়ে যায়; কোড এক্সপ্লোরার ব্যবহারকারীকে "ধরে রাখুন, আমি এখানে কাজ করছি", ...

এই কোথায় যাচ্ছে দেখুন? আমি এটি পছন্দ করি না এবং আমি বাজি ধরেছি যে ব্যবহারকারীরা এটি পছন্দ করবেন না। আমি কী মিস করছি? বৈশিষ্ট্যগুলির মধ্যে পার্স ফলাফলগুলি ভাগ করে নেওয়ার বিষয়ে আমার কীভাবে যাওয়া উচিত, তবে বৈশিষ্ট্যটির কাজটি কখন করা উচিত তা নিয়ন্ত্রণের মধ্যে রেখেই যায় ?

আমি যে কারণটি জিজ্ঞাসা করছি তার কারণ হ'ল আমি বুঝতে পেরেছিলাম যে যদি ব্যবহারকারী সক্রিয়ভাবে রিফ্রেশ করার সিদ্ধান্ত না নেয় এবং পার্সের ফলাফলগুলি "ক্যাশে" না আসে ততক্ষণ যদি আমি আসল কাজ স্থগিত করি ... তবে আমি একটি বৃক্ষদর্শনকে রিফ্রেশ করব এবং সম্ভাব্য বাসি পার্স ফলাফলে কোড ইস্যুগুলি সনাক্ত করা ... যা আক্ষরিক অর্থে আমাকে আবার স্কোয়ার একতে নিয়ে আসে, যেখানে প্রতিটি বৈশিষ্ট্য তার নিজস্ব বিশ্লেষণ ফলাফলের সাথে কাজ করে: বৈশিষ্ট্যের মধ্যে পার্স ফলাফলগুলি ভাগ করে নেওয়ার এবং কোনও সুন্দর ইউএক্স রাখার কোনও উপায় আছে কি?

কোডটি , তবে আমি কোড খুঁজছি না, আমি ধারণার সন্ধান করছি ।


2
কেবল একটি এফওয়াইআই, আমাদের পাশাপাশি একটি ইউজার এক্সপেরিয়েন্স.এসই সাইট রয়েছে। আমি বিশ্বাস করি এটি এখানে বিষয়বস্তুতে রয়েছে কারণ এটি ব্যবহারকারীর ইন্টারফেসের চেয়ে কোড ডিজাইনের বিষয়ে আরও আলোচনা করছে তবে আমি আপনার পরিবর্তনগুলি ইউআই পার্শ্বের দিকে আরও প্রবাহিত হয় এবং ইস্যুটির কোড / ডিজাইনের দিকটি নয় বলে আপনাকে জানাতে চাই।

আপনি যখন বিশ্লেষণ করছেন, এটি কি সর্বদাই বা কিছুই নয়? উদাহরণস্বরূপ: একটি ফাইলের পরিবর্তনগুলি কি একটি সম্পূর্ণ পুনর্বারম্ভকে ট্রিগার করে, বা কেবল সেই ফাইলটি এবং তার উপর নির্ভরশীলদের জন্য?
মরগেন

@ মরজেন দুটি জিনিস আছে: এএনটিএলআর VBAParserদ্বারা উত্পাদিত হয় এবং আমাকে একটি পার্স গাছ দেয়, তবে বৈশিষ্ট্যগুলি সেটিকে গ্রাস করে না। RubberduckParserপারসে ট্রি লাগে, এটা পদচারনা, এবং বিষয় একটি VBProjectParseResultযে রয়েছে Declarationবস্তু আছে তাদের সমস্ত Referencesসমস্যাগুলি সমাধান করা - যে কি বৈশিষ্ট্য ইনপুট জন্য নেওয়া .. তাই হ্যাঁ, এটা প্রায় কাছাকাছি একটি সম্পূর্ণ বা বাজে অবস্থা। RubberduckParserনা পুনরায় পার্স মডিউল যা যদিও পরিবর্তিত হয়নি স্মার্ট যথেষ্ট। তবে যদি কোনও বাধা থাকে তবে এটি পার্সিংয়ের সাথে নয়, কোড কোডটি রয়েছে with
ম্যাথিউ গুইনন

4
আমি মনে করি, এটি আমি এটির মতো করব: ব্যবহারকারী যখন একটি রিফ্রেশ ট্রিগার করে, তখন সেই টুল উইন্ডো পার্সকে ট্রিগার করে এবং দেখায় যে এটি কাজ করছে। অন্যান্য টুল উইন্ডো (গুলি) এখনও অবহিত করা হয়নি, তারা পুরানো তথ্য প্রদর্শন করে। পার্সার শেষ না হওয়া পর্যন্ত। এই মুহুর্তে, পার্সার সমস্ত সরঞ্জাম উইন্ডোগুলিকে নতুন তথ্য দিয়ে তাদের দৃষ্টিভঙ্গি সতেজ করার জন্য সংকেত দিত। পার্সার কাজ করার সময় ব্যবহারকারীর যদি অন্য কোনও টুল উইন্ডোতে যাওয়া উচিত হয় তবে উইন্ডোটি "ওয়ার্কিং ..." অবস্থায় প্রবেশ করবে এবং সংশোধন করার সংকেত দেবে। পার্সারটি একই সাথে সমস্ত উইন্ডোতে আপ টু ডেট তথ্য সরবরাহ করতে শুরু করবে।
মাস্টার -

2
@ মাস্টার আমি এই মন্তব্যটিকে উত্তর হিসাবেও উত্তর দেব।
রাবারডাক

উত্তর:


7

আমি যেভাবে সম্ভবত এটি পৌঁছাতে তা হ'ল নিখুঁত ফলাফল সরবরাহের দিকে কম মনোযোগ দেওয়া, এবং পরিবর্তে সেরা-প্রচেষ্টা পদ্ধতির দিকে ফোকাস করা। এটি কমপক্ষে নিম্নলিখিত পরিবর্তনগুলির ফলাফল করবে:

  • যুক্তিটি রূপান্তর করুন যা বর্তমানে আরম্ভের পরিবর্তে অনুরোধ করতে পুনরায় পার্স করা শুরু করে।

    পুনরায় পার্স করার অনুরোধ করার যুক্তিটি এরকম কিছু দেখতে শেষ হতে পারে:

    IF parseIsRunning IS false
      startParsingThread()
    ELSE
      SET shouldParse TO true
    END
    

    এটি পার্সার মোড়ানো যুক্তিকে যুক্ত করা হবে, এটি এর মতো দেখতে পারে:

    SET parseIsRunning TO true
    DO 
      SET shouldParse TO false
      doParsing()
    WHILE shouldParse IS true
    SET parseIsRunning TO false
    

    গুরুত্বপূর্ণ বিষয়টি হল সাম্প্রতিক পুনরায় পার্সের অনুরোধটি সম্মানিত না হওয়া অবধি পার্সার রান চালানো হয়েছে তবে নির্দিষ্ট সময়ে একাধিক পার্সার চলছে না।

  • ParseStartedকলব্যাক সরান । পুনঃ-পার্সের অনুরোধ করা এখন আগুন এবং ভুলে যাওয়া অপারেশন।

    পর্যায়ক্রমে, জিইউআইয়ের অংশের কিছু অংশে এটি একটি রিফ্রেশ ইন্ডিকেটর প্রদর্শন করা ব্যতীত অন্য কোনও কিছুতে রূপান্তর করুন যা ব্যবহারকারীর মিথস্ক্রিয়াকে অবরুদ্ধ করে না।

  • বাসি ফলাফলের জন্য ন্যূনতম হ্যান্ডলিং সরবরাহ করার চেষ্টা করুন।

    কোড এক্সপ্লোরারের ক্ষেত্রে, ব্যবহারকারী যে পদ্ধতিতে নেভিগেট করতে চায় তার জন্য বা নিখুঁত কোনও নাম খুঁজে পাওয়া যায় নি যদি সঠিক নাম না পাওয়া যায় তার জন্য যথাযথ সংখ্যক লাইনের উপরে এবং নীচের দিকে তাকানো যতটা সহজ।

    কোড ইন্সপেক্টরের পক্ষে উপযুক্ত কি হবে তা আমি নিশ্চিত নই।

আমি প্রয়োগের বিবরণ সম্পর্কে নিশ্চিত নই, তবে সামগ্রিকভাবে নেটবিন্স সম্পাদক এই আচরণটি কীভাবে পরিচালনা করেন তার সাথে এটি অনেকটা মিল similar এটি সর্বদা সতেজ হয় তা উল্লেখ করা সর্বদা খুব দ্রুত, তবে কার্যকারিতা অ্যাক্সেসকেও অবরোধ করে না।

বাসি ফলাফলগুলি প্রায়শই যথেষ্ট ভাল - বিশেষত যখন কোনও ফলাফলের সাথে তুলনা করা হয়।


1
দুর্দান্ত পয়েন্টগুলি, তবে আমার একটি প্রশ্ন রয়েছে: আমি ParseStarted[রিফ্রেশ] বোতামটি অক্ষম করতে ব্যবহার করছি ( Control.EnableRefresh(false))। যদি আমি সেই কলব্যাকটি সরিয়ে ফেলা হয় এবং ব্যবহারকারীকে এটি ক্লিক করতে দেয় ... তবে আমি নিজেকে এমন পরিস্থিতিতে ফেলব যেখানে আমার দুটি পার্সিং কাজ করছে একই সাথে ... অন্য কার্যের সাথে রিফ্রেশ অক্ষম না করে আমি কীভাবে এড়াতে পারি? পার্সিং হয়?
ম্যাথিউ গুইন্ডন

@ মাদুর মগ সমস্যার সেই দিকটি অন্তর্ভুক্ত করার জন্য আমি আমার উত্তর আপডেট করেছি।
মরজেন

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