在线程中执行时,方法无效,但在其他情况下有效-C# [英] Method doesn't work when executed in a thread, but works otherwise - C#

查看:162
本文介绍了在线程中执行时,方法无效,但在其他情况下有效-C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C#的初学者,我想执行以下操作:

I am a beginner in C# and I want to do the following:

Thread t = new Thread(new ThreadStart(this.play));
t.Start();

这是方法play:

    private void play()
    {
        playSong("path\\to\\song.mp3");
    }

    private static void playSong(String path)
    {
        mciSendString("open \"" + path + "\" type mpegvideo alias MediaFile", null, 0, IntPtr.Zero);
        mciSendString("play MediaFile", null, 0, IntPtr.Zero);
    }

    [DllImport("winmm.dll")]
    private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

当我像这样执行方法时:play();,不使用线程,这首歌播放得很好,但是如果我喜欢第一个代码摘录中的话,它就不会播放.

When I execute the method just like this: play();, without using threading, the song plays perfectly, but it doesn't play if I do like in the first code excerpt.

我怀疑是因为我需要在主线程中调用mciSendString方法.如果是这样,有人会告诉我该怎么做?还是告诉我如何使用线程工作?

I suspect that it happens because I need to call the mciSendString method in the main thread. If so, will someone tell me how can I do that? Or tell me how can I get it working using a thread?

感谢您的帮助.

-从此处编辑-

我不知道是否应该发布代码,因为它太大了,但是我会减少代码,以显示我想做的事情:

I don't know if I should post the code, cause it is kind of large, but I will reduce it, to show what I want to do:

我有一个Windows窗体应用程序,该应用程序在端口启动时启动在端口上侦听的套接字,该套接字用作服务器.该服务器作为请求接收将播放的歌曲的路径.如果我使用如下所示的play方法,则窗体将崩溃,但应用程序仍会监听我的请求.我知道我必须在后台执行此操作,以便表单控件不会崩溃,我只是不知道执行此操作的更好方法.

I have a windows forms application that starts a socket listening on a port when it begins, which works as a server. This server receives as requests paths to songs that it'll play. If I use the play method as shown below, the form crashes, but the application still listens to my requests. I understand that I have to do it in the background, so that the form controls won't crash, I just don't know the better way to do it.

    //Constructor
    public Main()
    {
        InitializeComponent();
        play();
    }

play()是这样的:

    private void play()
    {
        //Does the socket initialization
        do
        {
        //...
                while (true)
                {
                    //Reads text from client
                    //The text contains a string, indicating the path to the song.
                    byte[] bytesFrom = new byte[10025];
                    networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                    string dataFromClient = System.Text.Encoding.Default.GetString(bytesFrom);

                    //Plays the song from the received path
                    playSong(dataFromClient);

                    //...Do other stuff
                }
        } while (_serverOn);

        //Closes the socket connection
    }

    private static void playSong(String path)
    {
        mciSendString("open \"" + path + "\" type mpegvideo alias MediaFile", null, 0, IntPtr.Zero);
        mciSendString("play MediaFile", null, 0, IntPtr.Zero);
    }

推荐答案

我前段时间也遇到了类似的问题...屁股痛.

I had similar problem a while back... Pain in the butt.

您正在执行跨线程操作,这是不安全的.这就是它崩溃的原因.您对问题出在哪里绝对是正确的.

You are doing cross thread operations, that is not safe. That is the reason why it crashes. You are absolutely right about where you problem is.

以下是此线程操作的msdn文档 http://msdn.microsoft .com/en-us/library/ms171728.aspx

Here is msdn documentation on this thread operations http://msdn.microsoft.com/en-us/library/ms171728.aspx

您需要为mciSendString => mciSendStringCallBack添加委托定义

You need to add delegate definition for mciSendString => mciSendStringCallBack

delegate void mciSendStringCallBack(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

私有静态void playSong(字符串路径)中,您需要检查是否 InvokeRequired ,如果需要实例化回调并调用它.

In private static void playSong(String path) you need to check if InvokeRequired, if it is you need to instantiate callback and invoke it.

mciSendStringCallBack method = new mciSendStringCallBack(....); this.Invoke(method , new object[] { .....});

仔细阅读msdn站点上的示例,他们可以很好地演示其工作原理.

Look through the example on the msdn site, they do a good job demonstrating who it works.

-

您可能想尝试使用后台工作程序,它为您提供了多线程的处理方式,更易于使用.

You might want to try using background worker, it gives you multi threaded way of doing things, easier to work with.

这篇关于在线程中执行时,方法无效,但在其他情况下有效-C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆