c线程和一个等待表单

本文关键字:一个 等待 等待表 表单 线程 | 更新日期: 2023-09-27 18:28:11

我连接到一个webserive。当网络服务连接时,我想有一个里面有动画gif的等待表格。等待表格显示正确,但动画给出没有动画,它是固定的。

有人能帮我吗?我已经试过了:DoEvents,但gif仍然没有动画。

        // Create the new thread object
        Thread NewThread = new Thread(new ThreadStart(RunThread));           
        // Start the new thread.
        NewThread.Start();
        // Inform everybody that the main thread is waiting
        FRM_Wait waitingDialog = new FRM_Wait();
        waitingDialog.Show();
        waitingDialog.Activate();
        Application.DoEvents(); 
        // Wait for NewThread to terminate.
        NewThread.Join();
        // And it's done.
        waitingDialog.Close();
        MessageBox.Show("Upload erfolgreich erledigt.", "Upload Erfolgreich",
             MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
    }
    public void RunThread()
    {         
         mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient();
        int status = servicedev.addEvent(videosNames, videos);         
    }

c线程和一个等待表单

不要在UI线程内的线程上调用Join。相反,在任务完成之前禁用任何不想执行的控件(例如按钮),然后在操作完成后将回调到UI线程中,因此将"and it’s done"代码移到一个新方法中,该方法在操作结束时调用。如果您使用的是.NET 4,我建议使用TPL,因为它可以更容易地表示"正在进行的任务"并为其添加延续

问题来自您的加入。join是同步的,所以基本上是让UI等待线程完成它的工作。

您希望使用回调函数返回到您的UI。

编辑:我已被解密

您的问题在这里:

NewThread.Join();

这会阻塞UI线程,直到NewThread结束。

这里有一种方法:

private myDelegate;
// ...
myDelegate = new Action(RunThread);
myDelegate.BeginInvoke(new AsyncCallback(MyCallback),null);
// You RunThread method is now running on a separate thread
// Open your wait form here
// ...
// This callback function will be called when you delegate ends
private void MyCallback(IAsyncResult ar)
{
     myDelegate.EndInvoke(ar);
     // Note this is still not the UI thread, so if you want to do something with the UI you'll need to do it on the UI thread.
     // using either Control.Invoke (for WinForms) or Dispatcher.Invoke (for WPF)
}

Thread.Join是一个阻塞调用,它不会泵送消息,所以这是您的问题。通常建议避免调用任何导致UI线程阻塞的同步机制。

这里是一个使用Task类和Invoke封送处理技术的解决方案。

private void async InitiateWebService_Click(object sender, EventArgs args)
{
  FRM_Wait waitingDialog = new FRM_Wait();
  waitingDialog.Show();
  Task.Factory.StartNew(
    () =>
    {
      mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient();
      int status = servicedev.addEvent(videosNames, videos);
      waitingDialog.Invoke(
        (Action)(() =>
        {
          waitingDialog.Close();
        }));
    });
}

以下是使用原始Thread的解决方案。

private void async InitiateWebService_Click(object sender, EventArgs args)
{
  FRM_Wait waitingDialog = new FRM_Wait();
  waitingDialog.Show();
  var thread = new Thread(
    () =>
    {
      mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient();
      int status = servicedev.addEvent(videosNames, videos);
      waitingDialog.Invoke(
        (Action)(() =>
        {
          waitingDialog.Close();
        }));
    });
  thread.Start();
}

C#5.0通过其新的asyncawait关键字1使这种模式更加容易。

private void async InitiateWebService_Click(object sender, EventArgs args)
{
  FRM_Wait waitingDialog = new FRM_Wait();
  waitingDialog.Show();
  await Task.Run(
    () =>
    {
      mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient();
      int status = servicedev.addEvent(videosNames, videos);         
    });
  waitingDialog.Close();
}

1尚未发布。