c # - индикатор выполнения [Threading] Операция кросс-потока недопустима: элемент управления «progressBar» доступен из потока, отличного от потока, в котором он был создан - PullRequest
2 голосов
/ 08 сентября 2010

Я застрял с вышеуказанным вопросом. У меня есть много решений, но ни одно из них не работает для меня. Пожалуйста, найдите здесь мой код

private void btnRunQuery_Click(object sender, EventArgs e)
    {
        try
        {

            Thread ProcessThread = new Thread(Process);
            ProcessThread.Start();

            Thread.CurrentThread.Join();
        }
        catch
        {
            Debug.WriteLine("Error in model creation");
            Console.WriteLine("Error in model creation");
        }
        finally
        {
            //dsModel = null;
        }
    }


private void Process()
    {

        using (var dataContext = new IControlerDataContext())
        {
            dataContext.EnlistTransaction();

            IItemPropertyRepository itemPropertyRepository = ObjectContainer.Resolve<IItemPropertyRepository>();
            IList<ItemProperty> itemPropertyCollection = itemPropertyRepository.LoadAll();
            totalCount = itemPropertyCollection.Count;
            currentCount = 0;

            foreach (var itemProperty in itemPropertyCollection)
            {
                try
                {
                    message = string.Empty;
                    currentCount++;
                    if (itemProperty.DeletedDate == null && (itemProperty.MetaItemProperty.ValueType == MetaItemPropertyValueType.MetaItemTableProperty || itemProperty.MetaItemProperty.ValueType == MetaItemPropertyValueType.MetaItemTableMultiSelectProperty))
                    {
                        //Property refresh issue in only applicable for table and multitable property.
                        //Need to filter the itemproperty for Table and multitable select property.
                        message = ProcessItemProperty(itemProperty);
                        //txtLogDetails.Text += message + Environment.NewLine;
                        //txtLogDetails.Refresh();
                        //txtLogDetails.ScrollToCaret();
                    }
                    //Log(message);
                    //progressBar.Value = (Int32)(currentCount * 100 / totalCount);
                    //progressBar.Refresh();
                    Invoke(new MyDelegate(ShowProgressBar), (Int32)(currentCount * 100 / totalCount));

                }
                catch (Exception ex)
                {
                    txtLogDetails.Text += "EXCEPTION ERROR : " + itemProperty.Id.ToString();
                    dataContext.RollBackTransaction();
                }
            }
            dataContext.CompleteTransaction();
        }
    }

 delegate void MyDelegate(int percentage);
    private void ShowProgressBar(int percentage)
    {
        progressBar.Value = percentage;
        progressBar.Refresh();
        //txtLogDetails.Text = message;
    }

Когда выполняется «Invoke (new MyDelegate (ShowProgressBar), (Int32) (currentCount * 100 / totalCount));» эта линия выходит из области видимости. Он идет внутрь и никогда не вернулся. и также не пойман в исключении.

Может кто-нибудь, пожалуйста, помогите мне с этим?

Спасибо, Махеш

Ответы [ 2 ]

5 голосов
/ 08 сентября 2010

Элемент управления progressBar должен быть доступен из потока, в котором он был создан.Используйте BeginInvoke .

Я бы заменил эту строку ...

Invoke(new MyDelegate(ShowProgressBar), (Int32)(currentCount * 100 / totalCount)); 

... этой ... ... 1009 *

this.progressBar.BeginInvoke( 
    (MethodInvoker)delegate() { 
        this.progressBar.Value =
           Convert.ToInt32(currentCount * 100 / totalCount); } );

Или вы можете заменить эти строки ...

progressBar.Value = percentage; 
        progressBar.Refresh(); 
        //txtLogDetails.Text = message; 

... этими строками ...

this.progressBar.BeginInvoke( 
    (MethodInvoker)delegate() { 
    progressBar.Value = percentage; 
    progressBar.Refresh(); 
    //txtLogDetails.Text = message; 

    } );
0 голосов
/ 08 сентября 2010

Мне кажется, проблема в том, что вы блокируете поток пользовательского интерфейса с помощью Thread.Join.

Thread.Join теоретически будет продолжать качать сообщения пользовательского интерфейса, но в действительности это не всегда работает.

см. Блог Криса Брамма здесь .Специально

Чистый эффект заключается в том, что мы всегда будем прокачивать вызовы COM, ожидающие входа в вашу STA.И любые SendMessages для любых окон будут обслуживаться.Но большинство сообщений PostMessages будут отложены до тех пор, пока вы не закончите блокировку.

Вы должны позволить завершить событие кнопки, и новая ветка отправит сообщение обратно, когда это будет сделано (например, с помощью backgroundworker или какого-либо другого асинхронного).framework)

(Ваш оператор catch в любом случае бесполезен, поскольку он будет перехватывать только исключения созданий потоков.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...