–еализаци€ BackgroundWorker в Mono GTK# Monodevelop .NET

08:03:2013 –≥.

¬ заметке рассматриваетс€ реализаци€ подоби€ BackgroundWorker в GTK# на Mono .NET. ѕодоби€, поскольку такой реализации, к сожалению, в наброре стандартных элементов не существует. ѕоэтому € разработал подобие такого класса и использую его в программах.

¬ противном случае необходимо было бы выходить из ситуации, использу€ делегаты, использовать напр€мую класс Thread или искать другие методы. ¬се это €вл€етс€ достаточно ресурсоемким и не совсем универсальным. ј на платформе Mono .NET, кроме того, иногда наблюдаютс€ некорректности в работе IAsyncResult. ѕредлагаемый класс позвол€ет обойти эти некорректности и с легкостью использовать возвр€щаемые значени€ из потока в GTK#.

–еализуем абстрактный класс.   примеру, BackgroundWorker - BackgroundWorker.cs:

using System;
using Gtk;
using System.Threading;

namespace X
{
    public abstract class BackgroundWorker
    {
        protected object result;
        protectedThreadNotify completed;
        protectedThread asyncThread;

        public BackgroundWorker ()
        {
           result = null;
           completed = newThreadNotify (newReadyEvent (ready));
           asyncThread = newThread(newParameterizedThreadStart(DoWork));
        }

        protected abstract void DoWork(object param = null);

        public void RunWorkerAsync(object param = null)
        {
           asyncThread.Start(param);
        }

        protected virtual void ready(){}
    }
}

Ќебольшие по€снени€ к коду - мы создали абстрактный класс, наследниками которого будут €вл€тьс€ все классы, в которых нужно реализовать асинхронный вызов.

¬нутри данного класса асинхронно вызываема€ функци€ одна - DoWork, котора€ запускаетс€ с помощью функции RunWorkerAsync и не может быть запущена напр€мую. ¬ эту функцию предусмотрена возможность передачи любых параметров в виде object, который также можно упустить т.к. он €вл€етс€ параметром по умолчанию. ¬ любом месте реализации класса-наследника мы можем вызвать completed.WakeupMain(); , выполнив, таким образом, функцию ready в родительском потоке из которого можно безопасно отображать сообщени€ или измен€ть элементы управлени€ вашего приложени€ Mono.

Ќужно отметить, что ready помечен как virtual и необ€зателен к реализации. RunWorkerAsync будет присутствовать в каждом наследнике, а DoWork необходимо будет реализовывать самосто€тельно.

“еперь перейдем к созданию и использованию наследника, использующего многопоточность в Mono .NET GTK#. ƒл€ примера реализуем простой класс, провер€ющий соединение с базой данных.

private classDBChecker :BackgroundWorker
{
    protected override void DoWork(object param)
    {
        result = false;

        if(param != null)
        {
            MySqlConnection dbcon;
            dbcon = newMySqlConnection(param.ToString());
            try
            {
                dbcon.Open();
                result = true;
            }
            catch { }
        }
      completed.WakeupMain();
    }

    protected override void ready()
    {
       if(this.result == null)
          return;
       if(!(this.result is bool))
          return;
       if(bool.Parse(this.result.ToString()) == true)
           MessageBox.Show("—оединение успешно установлено");
       else
           MessageBox.Show("ѕараметры подключени€ не верны");
    }
}

¬ этом коде result - объект, наследуемый из родительского класса, как и вызов completed.WakeupMain() .

ќстаетс€ продемонстрировать вызов из программного кода:

DBChecker checker = newDBChecker();
checker.RunWorkerAsync(_connectionString);

 ак видите, пользоватьс€ асинхронным взовом с помощью подобного класса теперь легко. ƒанный класс легко дорабатываетс€ до необходимого вам функционала. «десь показана основна€ логика работы асинхронного вызова в Mono с подобием BackgroundWorker Windows Forms C#.

P.S:¬озможно у начинающих программистов будет проблема с реализацией данного класса - если он будет реализован внутри их основного класса, то если потребуетс€ не простое уведомление, а обращение к элементам управлени€ или переменным основного класса - это приведет к ошибке компил€ции.  ак ее решить описано тут.

 

ƒобавить комментарий


«ащитный код
ќбновить

« TextBox или Entry enabled = false в GTK# Mono .Net Mono MySQL подключение в .NET »

‘отоальбом

fotic.jpg

ќблако “егов