启动屏幕等待线程完成

发布于 2024-07-11 00:23:49 字数 3121 浏览 5 评论 0原文

我仍然遇到闪屏问题。 我不想使用属性 SC.TopMost=true

现在我的应用场景如下:

在progeram.cs中:

[STAThread]
static void Main()
{
    new SplashScreen(_tempAL);// where _tempAL is an arrayList
    Application.Run(new Form1(_tempAL));
}

在SplashScreen类中:

public SplashScreen(ArrayList _Data)
{
    DisplaySplash()
} 
private void DisplaySplash()
{
    this.Show();
    this.TopMost = true;
    this.CenterToScreen();
    this.SetTopLevel(true);

    _allServerNarrators = new string[10];
    for (int i = 0; i < _allServerNarrators.Length; i++)
        _allServerNarrators[i] = null;

    GetFromServer();

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

}
private void GetFromServer()
{
    _serverNarrators = new ArrayList();
    string _file = "Suras.serverNar";

    if (!Directory.Exists("c:\\ASGAQuraan"))
        Directory.CreateDirectory("c:\\ASGAQuraan");

    while (counter < 4 && _serverFiles == null)
    {
        if (Download("c:\\ASGAQuraan", _ftpServerIP, _file))
        {
            StreamReader _strReader = new StreamReader
                         ("c:\\ASGAQuraan\\"+_file,System.Text.Encoding.Default);
            string _line = _strReader.ReadLine();
            string _word;

            while (true)
            {
                while (_line != null)
                {
                    _word = _line.Substring(0, _line.IndexOf("*"));
                    int _narId = Convert.ToInt32(_word);
                    _line = _line.Substring(2);
                    int k = 0;
                    _serverNarratorNode = new ArrayList();
                    while (true)
                    {
                        int ind = _line.IndexOf("*");
                        if (ind > 0 && ind < _line.Length)
                        {
                            string str = _line.Substring(0, (ind));
                            if (k == 0)
                            {
                                _allServerNarrators[_narId] = str;
                                _serverNarratorNode.Add(str);
                            }
                            else
                            {
                                _serverNarratorNode.Add(str);
                            }
                            _line = _line.Substring(ind + 1);
                            k++;
                        }
                        else
                        {
                            _line = null;
                            break;
                        }
                    }
                    _serverNarrators.Add(_serverNarratorNode);
                    _serverFiles = "added";
                }
                _line = _strReader.ReadLine();
                if (_line == null)
                {
                    break;
                }
            }
        }
        else
            counter++;
    }
}

我想要的是在启动屏幕类中等待线程完成的东西。

如需了解更多详情,请告诉我需要告诉您的内容。

I still have a problem with the splash screen. I don't want to use the property SC.TopMost=true.

Now my application scenario is as follows:

in progeram.cs:

[STAThread]
static void Main()
{
    new SplashScreen(_tempAL);// where _tempAL is an arrayList
    Application.Run(new Form1(_tempAL));
}

in SplashScreen class:

public SplashScreen(ArrayList _Data)
{
    DisplaySplash()
} 
private void DisplaySplash()
{
    this.Show();
    this.TopMost = true;
    this.CenterToScreen();
    this.SetTopLevel(true);

    _allServerNarrators = new string[10];
    for (int i = 0; i < _allServerNarrators.Length; i++)
        _allServerNarrators[i] = null;

    GetFromServer();

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

}
private void GetFromServer()
{
    _serverNarrators = new ArrayList();
    string _file = "Suras.serverNar";

    if (!Directory.Exists("c:\\ASGAQuraan"))
        Directory.CreateDirectory("c:\\ASGAQuraan");

    while (counter < 4 && _serverFiles == null)
    {
        if (Download("c:\\ASGAQuraan", _ftpServerIP, _file))
        {
            StreamReader _strReader = new StreamReader
                         ("c:\\ASGAQuraan\\"+_file,System.Text.Encoding.Default);
            string _line = _strReader.ReadLine();
            string _word;

            while (true)
            {
                while (_line != null)
                {
                    _word = _line.Substring(0, _line.IndexOf("*"));
                    int _narId = Convert.ToInt32(_word);
                    _line = _line.Substring(2);
                    int k = 0;
                    _serverNarratorNode = new ArrayList();
                    while (true)
                    {
                        int ind = _line.IndexOf("*");
                        if (ind > 0 && ind < _line.Length)
                        {
                            string str = _line.Substring(0, (ind));
                            if (k == 0)
                            {
                                _allServerNarrators[_narId] = str;
                                _serverNarratorNode.Add(str);
                            }
                            else
                            {
                                _serverNarratorNode.Add(str);
                            }
                            _line = _line.Substring(ind + 1);
                            k++;
                        }
                        else
                        {
                            _line = null;
                            break;
                        }
                    }
                    _serverNarrators.Add(_serverNarratorNode);
                    _serverFiles = "added";
                }
                _line = _strReader.ReadLine();
                if (_line == null)
                {
                    break;
                }
            }
        }
        else
            counter++;
    }
}

What I want is something in the splash screen class which waits until the thread finishes.

For more details, please tell me what I need to tell you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

月亮坠入山谷 2024-07-18 00:23:49

同样的问题,同样的答案:

.NET 框架对闪屏具有出色的内置支持。 启动一个新的WF项目,Project + Add Reference,选择Microsoft.VisualBasic。 添加一个新表单,将其命名为 frmSplash。 打开 Project.cs 并使其看起来像这样:

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

namespace WindowsFormsApplication1 {
  static class Program {
    [STAThread]
    static void Main(string[] args) {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      new MyApp().Run(args);
    }
  }
  class MyApp : WindowsFormsApplicationBase {
    protected override void OnCreateSplashScreen() {
      this.SplashScreen = new frmSplash();
    }
    protected override void OnCreateMainForm() {
      // Do your time consuming stuff here...
      //...
      System.Threading.Thread.Sleep(3000);
      // Then create the main form, the splash screen will close automatically
      this.MainForm = new Form1();
    }
  }
}

Same question, same answer:

The .NET framework has excellent built-in support for splash screens. Start a new WF project, Project + Add Reference, select Microsoft.VisualBasic. Add a new form, call it frmSplash. Open Project.cs and make it look like this:

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

namespace WindowsFormsApplication1 {
  static class Program {
    [STAThread]
    static void Main(string[] args) {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      new MyApp().Run(args);
    }
  }
  class MyApp : WindowsFormsApplicationBase {
    protected override void OnCreateSplashScreen() {
      this.SplashScreen = new frmSplash();
    }
    protected override void OnCreateMainForm() {
      // Do your time consuming stuff here...
      //...
      System.Threading.Thread.Sleep(3000);
      // Then create the main form, the splash screen will close automatically
      this.MainForm = new Form1();
    }
  }
}
鲜血染红嫁衣 2024-07-18 00:23:49

通过在调用 Application.Run() 之前创建 UI,您已经进入了危险区域。 Application.Run 本质上是程序的消息泵。 通过在启动应用程序的消息泵之前显示 UI,可以使典型的 UI 交互在过早的 UI 上实际上变得不可能。 对于闪屏来说,这可能看起来不相关,但如果(例如)有请求让闪屏在单击时消失,或者您想使用BackgroundWorker,那么这将很重要。

这些可以通过在启动屏幕中创建消息泵来解决(通过调用 ShowDialog() 而不是 Show() 使其成为模态),但这只是治疗症状,而治疗问题实际上并不那么困难。

在这种情况下,我强烈鼓励 nobugz 的回答。 该框架提供您所需的支持。 虽然 Microsoft.VisualBasic 命名空间中的功能并不总是很容易被 C# 程序员发现,但对于此类情况,它们确实可以节省时间和救星。

祝你好运!

You've entered dangerous territory by creating UI prior to your call to Application.Run(). Application.Run is essentially your program's message pump. By displaying the UI before you start the application's message pump, you make typical UI interaction effectively impossible on the premature UI. For a splash screen this may not seem relevant, but it will matter if (e.g.) there's a request to make the splash screen disappear if it's clicked on, or you want to use a BackgroundWorker.

These can be worked around by creating a message pump in your splash screen (by making it modal via a call to ShowDialog() instead of Show()), but that's treating the symptom when treating the problem really isn't that difficult.

I'd strongly encourage nobugz's answer in this case. The framework provides the support you need. While features in the Microsoft.VisualBasic namespace aren't always very discoverable to C# programmers, they can be a real timesaver and lifesaver for cases like this.

Good luck!

巨坚强 2024-07-18 00:23:49

跨两个线程进行跟踪有点令人困惑,但我要尝试说一下......

我不完全理解您的设计,但如果问题是当您启动第二个应用程序时,启动屏幕形式变成白色...这很可能是由于启动屏幕正忙于执行 GetFromServer() 中的所有代码。 太忙了,以至于没有时间重新粉刷自己。

为了解决这个问题,我建议您使用 BackGroundWorker 组件执行 GetFromServer 方法。 这将在单独的线程中运行该方法,并让表单的线程自由地重新绘制自身。

Following across 2 threads is a bit confusing, but I'm going to take a stab and say this...

I don't fully understand your design here, but if the issue is that when you launch a second application the splash screen form turns white... It's most likely due to the fact that splash screen is busy executing all of that code in GetFromServer(). So busy that it has no time to re-paint itself.

To remedy this problem I would suggest that you use the BackGroundWorker component to execute the GetFromServer method. This will run that method in a separate thread and leave the form's thread free to re-paint itself.

烟雨凡馨 2024-07-18 00:23:49

不幸的是,我还没有足够的声誉来评论某人的答案。 :( 这意味着恐慌上校对汉斯·帕桑斯答案的评论< /a>

的问题是从 new FormMain(args) 显示的 MessageBox 将显示在启动屏幕后面,关键是从线程中调用 MessageBox。启动画面运行于:

splashScreen.Invoke(new Action(() => {
    MessageBox.Show(splashScreen, "the message");
}));

其中 splashScreen 是对在 OnCreateSplashScreen 中创建的启动画面对象的引用,显然必须将其提供给新的 Form1对象。

Unfortunately I don't have enough reputation to comment on someones answer yet. :( This is meant to be the answer to Colonel Panics comment on Hans Passants answer.

His problem was that a MessageBox shown from new FormMain(args)will be shown behind the splash screen. The key is to invoke the MessageBox from the thread the splash screen runs in:

splashScreen.Invoke(new Action(() => {
    MessageBox.Show(splashScreen, "the message");
}));

Where splashScreen is a reference to the splash screen object that has been created in OnCreateSplashScreen and obviously has to be given to the new Form1 object.

執念 2024-07-18 00:23:49

您确实应该提供有关您的问题的更多详细信息。 我可能完全错了,但我会在黑暗中尝试一下。 根据我的想象,您想要显示启动画面,在另一个线程中进行一些处理,然后启动画面在完成后消失。

为此,您需要将 GetFromServer() 调用移至 BackgroundWorker。 然后将

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

代码移至 BackgroundWorker_RunWorkerCompleted 事件处理程序。

要使用BackgroundWorker

1) 初始化BackGroundWorker

  BackgroundWorker myWorker = new BackgroundWorker();

2) 添加事件处理程序

  myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
  //put the work you want done in this one

  myWorker.RunWorkerCompleted += 
      new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
  //this gets fired when the work is finished

3) 将代码添加到事件处理程序。

4) 调用myWorker.RunWorkerAsync()开始工作。

作为一个单独的说明,您似乎没有对传递给初始屏幕构造函数的 ArrayList 执行任何操作。 这是故意的吗?

You really should give more details about your problem. I could be completely wrong, but I'm going to take a shot in the dark. From what I'm imagining is going on and you want, you want the splash screen to show, do some processing in another thread, then the splash screen to go away when finished.

To do this, you're going to want to move the GetFromServer() call to a BackgroundWorker. Then move the

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

code to the BackgroundWorker_RunWorkerCompleted event handler.

To use the BackgroundWorker:

1) Initialize the BackGroundWorker

  BackgroundWorker myWorker = new BackgroundWorker();

2) Add event handlers

  myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
  //put the work you want done in this one

  myWorker.RunWorkerCompleted += 
      new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
  //this gets fired when the work is finished

3) Add code to the event handlers.

4) Call myWorker.RunWorkerAsync() to start working.

As a separate note, you don't seem to be doing anything with the ArrayList that you're passing to the splash screen's constructor. Is this intended?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文