2013-09-09 2 views
0

Я разрабатываю приложение Windows Forms, которое обращается к службе WCF. У меня возникла большая проблема, и я не могу предсказать причину этого. Даже отладчик Visual Studio не показывает никаких исключений в представлении «Выход». Сценарий подобен этому, у меня есть пользовательский элемент управления, на котором есть linkLabel. Всякий раз, когда нажимается метка ссылки, открывается форма, и объект класса передается ей. Определение класса этого объекта находится на службе WCF на удаленном сервере. Теперь проблема в том, что когда я нажимаю linkLabel, форма открывается, полностью загружая каждый свой компонент в соответствии с переданным ему объектом класса. Но когда я закрываю эту форму и снова нажимаю на нее linkLabel, форма открывается, но сразу же зависает после загрузки некоторых элементов. Я пробовал много вариантов кода. Отредактировано множество частей кода, которые, как я думаю, могут повлиять. Но ни одна из них не показала разницы. Так как я не знаю, где на самом деле есть код, я отправляю код и функции, которые вызывается после нажатия кнопки linkLabel.Форма замерзает при открытии во второй раз

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 
{ 
     Enabled = false; 
     string temp = Title.Text; 
     Title.Text = "Opening..."; 
     System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(openTopic)); 
     t.Start(); 

     Title.Text = temp; 
     Enabled = true; 
} 

void createTopicWindow() 
{ 
     TopicViewer t = new TopicViewer(t); 
     Invoke(new Action(() => t.Show())); 
} 
private void openTopic() 
{ 
     Invoke(new Action(() => createTopicWindow())); 
} 

Выше отредактированный код, так как я был перед тем, как Cross thread exception.

Ниже приводится код конструктора формы, который вызывается при нажатии на linkLabel:

try 
{ 
     InitializeComponent(); 
     this.t = topic; 
     if (IsHandleCreated == false) 
      CreateHandle(); 
     System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ThreadStart(loadTopic)); 
     th.Start(); 
     Common.openedTopics.Add(this); 
     AddComment addComment1 = new AddComment(); 
     addComment1.Topic = t; 
     addComment1.Dock = DockStyle.Fill; 
     panel5.Controls.Add(addComment1); 
     backgroundWorker1.RunWorkerAsync(); 
    } 
    catch (Exception) 
    { } 

void loadTopic() 
{ 

    Invoke(new Action(()=>tHead = new TopicHeader())); 
    Global.SetControlPropertyThreadSafe(tHead,"Topic", t); 
    Global.SetControlPropertyThreadSafe(tHead,"Dock", DockStyle.Fill); 
    Invoke(new Action(()=>panel1.Controls.Add(tHead))); 
    Global.SetControlPropertyThreadSafe(this,"Text", t.Title + " - Topic Viewer"); 
    if (t.Description.Trim().Length > 0) 
    { 
     Global.SetControlPropertyThreadSafe(webBrowser1, "DocumentText", t.Description); 
    } 
    else 
    { 
     Invoke(new Action(() => tabControl1.TabPages[0].Dispose())); 
    } 

    Global.SetControlPropertyThreadSafe(tabPage2, "Text", "Comments (" + client.getComCount(t.TopicID) + ") "); 

} 

TopicHeader еще один небольшой пользовательский элемент управления. Пожалуйста, скажите, пожалуйста, решение этого?

+1

Почему вы делаете это: поймать (Exception) {} Вы скрываются проблемы. –

+0

Отсутствует LoadTopic –

+0

Какая причина для создания формы через поток в потоке gui? –

ответ

2

Если вы используете .Net 4.5, то использование async/await было бы самым простым решением. Таким образом, вам не нужны никакие Invoke s

async private void Form1_Load(object sender, EventArgs e) 
{ 
    string s = await Task<string>.Factory.StartNew(LongRunningTask, 
               TaskCreationOptions.LongRunning); 
    this.Text = s; 
} 

string LongRunningTask() 
{ 
    Thread.Sleep(10000); 
    return "------"; 
} 
+0

На самом деле проблема не в долгосрочной перспективе. Как я уже упомянул о его загрузке в первый раз. Но когда я нажимаю 'linkLabel' во второй раз, он зависает. –

+1

@AishwaryaShiva Как насчет изменения вашего кода и тестирования этого подхода? Поскольку вы не имеете дело с потоками, вызывает и т. Д., Это уменьшает вероятность ошибки. – I4V

+1

ok Я попробую и расскажу вам после некоторого времени. Мне нужно изменить многие части моего кода, чтобы реализовать ваше предложение. –

2

Я не могу дать прямой ответ на ваш вопрос, но это может задержать.

public void Form_Load() 
{ 
    // do some stuff on the gui-thread 



    // i need to do something that takes a long time: 
    ThreadPool.QueueUserWorkItem((state) => 
    { 
     // i'll execute it on the ThreadPool 
     // Long running code.... 




     // update results in mainform on gui thread. 
     Invoke(new Action(delegate 
     { 
      // because the invoke will execute this on the gui-thread, you'll able to update controls. 

      // update my gui controls.    
      DataGrid.Source = myReceiveDataThing; 
     })); 
    } 
} 

Вы могли бы расширить этот код, чтобы проверить, действительно ли форма.

+0

На самом деле проблема не в долгосрочной перспективе. Как я уже упомянул о его загрузке в первый раз. Но когда я нажимаю 'linkLabel' во второй раз, он зависает. –

+0

Благодаря @Jeroen это помогло мне узнать что-то новое о пулах потоков и потоков.:) +1 к вам –