Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 提高线程性能_C#_Multithreading_Performance - Fatal编程技术网

C# 提高线程性能

C# 提高线程性能,c#,multithreading,performance,C#,Multithreading,Performance,我有一个带有启动按钮的应用程序,可以调用长时间运行的功能。整齐 为了添加一个停止按钮,我为这个函数添加了一个线程,以避免UI冻结,并能够随时停止处理 没有线程的代码平均需要12分钟来完成处理,但是使用下面的线程方式 需要4倍以上的时间。下面显示了启动按钮的代码,其中称为函数“LongRunningFunction”。功能 需要字符串参数才能使用“LongRunningFunction(Somestring)” 我已经用Task.Run和Task.Factory.StartNew进行了测试,但这两

我有一个带有启动按钮的应用程序,可以调用长时间运行的功能。整齐 为了添加一个停止按钮,我为这个函数添加了一个线程,以避免UI冻结,并能够随时停止处理

没有线程的代码平均需要12分钟来完成处理,但是使用下面的线程方式 需要4倍以上的时间。下面显示了启动按钮的代码,其中称为函数“LongRunningFunction”。功能 需要字符串参数才能使用“LongRunningFunction(Somestring)”

我已经用Task.Run和Task.Factory.StartNew进行了测试,但这两种方法的测试结果相同

有没有其他方法可以为我的案例设置一个不会对性能造成太大影响的线程

public partial class Form1 : Form
{
    CancellationTokenSource cts = new CancellationTokenSource(); // Create the token source.
    public Form1()
    {
        InitializeComponent();
    }
    private void Start_Click(object sender, EventArgs e)
    {
        if (cts != null)
        {
            cts.Cancel();
        }
        cts = new CancellationTokenSource();
        Task.Run(()=> LongRunningFunction(Somestring, cts.Token), cts.Token);            
        //Task.Factory.StartNew(() => LongRunningFunction(Somestring, cts.Token), cts.Token, TaskCreationOptions.None, TaskScheduler.Default); 
    }
    private void Stop_Click(object sender, EventArgs e)
    {
        if (cts != null)
        {
            cts.Cancel();
            cts = null;
            MessageBox.Show("Processing cancelled");
        }
    }
    public void LongRunningFunction(string String, CancellationToken token)
    {
        //Long running processing
        //...
        MessageBox.Show("Processing finished");
    }
}
更新: 我唯一改变的是声明函数的方式,并在while循环中添加了if语句 这是函数的内部。如下所示:

  • 添加CancelationToken是为了能够在按下停止按钮时停止处理
在没有线程的情况下,我声明如下函数:

public void LongRunningFunction(string String) 
{ 
    while (condition)
    {
        //My code within While loop
    }
    MessageBox.Show("Processing finished");
}
public void LongRunningFunction(string String, CancellationToken token) 
{ 
    while (condition)
    {
        if (token.IsCancellationRequested)
        {
            break;
        }       
        //My code within While loop
    }
    if (!token.IsCancellationRequested)
    {
        MessageBox.Show("Processing finished");
    }       
}
public void LongRunningFunction(string fileName)
{
    using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)))
    {
        // some code
    }
}       
使用Thread,我定义了如下函数:

public void LongRunningFunction(string String) 
{ 
    while (condition)
    {
        //My code within While loop
    }
    MessageBox.Show("Processing finished");
}
public void LongRunningFunction(string String, CancellationToken token) 
{ 
    while (condition)
    {
        if (token.IsCancellationRequested)
        {
            break;
        }       
        //My code within While loop
    }
    if (!token.IsCancellationRequested)
    {
        MessageBox.Show("Processing finished");
    }       
}
public void LongRunningFunction(string fileName)
{
    using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)))
    {
        // some code
    }
}       
更新2: 在LongRunningFunction()内部调用另一个打印行的函数。就像下面

    public void LongRunningFunction(string fileName, CancellationToken token)
    {
        StreamWriter writer = new StreamWriter(@outputfile, true, Encoding.UTF8, 4096);

        using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)))
        {
            List<byte> buffer = new List<byte>();
            List<string> buffer1 = new List<string>();

            SoapHexBinary hex = new SoapHexBinary();

            while (chunk.Length > 0)
            {
                if (token.IsCancellationRequested) // ### For Cancel Thread ###
                {
                    break;
                }   // ### For Cancel Thread ###    

                    chunk = reader.ReadBytes(1024);

                    foreach (byte data in chunk)
                    {
                        if (somecondition)
                        {
                            buffer.Add(data);                           
                        }
                        else if (other condition)
                        {
                            buffer.Add(data);
                            PrintFunction(buffer, hex, outputfile, writer); // Print Line
                        }
                        else if (some other condition)
                        {
                            buffer.Add(data);
                        }
                    }                   
            }           
            if (!token.IsCancellationRequested)
            {
                MessageBox.Show("Processing finished");
            }

        }

        if (writer != null)
        {
            writer.Dispose();
            writer.Close();
        }
    }       
    private void PrintFunction(List<byte> buffer, SoapHexBinary hex, string outputfile, StreamWriter writer)
    {
            if (buffer.Count > 0)
            {
                if (buffer.Count >= lowlimit)
                {
                    hex.Value = buffer.ToArray();
                    string Register = hex.ToString();

                    Regex pattern1 = new Regex(@"some pattern");

                    if (pattern1.IsMatch(Register))
                    {
                        Match l1 = Regex.Match(Register, @"somepattern", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                        writer.Write("{0}|{1}|{2}", Convert.ToInt32(l1.Groups[1].ToString(), 16), l1.Groups[2].Value, l1.Groups[3].Value);
                        Match l2 = Regex.Match(Register, @"otherpattern", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                        if (l2.Success)
                        {
                            foreach (Match m in Regex.Matches(l2.Groups[2].ToString(), pattern2, RegexOptions.IgnoreCase | RegexOptions.Compiled))
                            {
                                //Some foreach code
                            }
                            foreach (Match x in Regex.Matches(var, @"pattern"))
                            {
                                //come code
                            }
                            writer.WriteLine("," + String.Join(",", var1));
                        }
                        else
                        {
                            writer.WriteLine();
                        }
                    }
                }
            }
            buffer.Clear();
    }
可能是这样的,也可能是怎样的

private void LongRunningFunction(string fileName)
{
    MethodInvoker action = delegate
    {
        using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)))
        {
            // some code
        }
    };
}

使用中断线程

        Thread thread;

        public MainWindow()
        {
            InitializeComponent();
        }

        private async void StartButtonClick(object sender, RoutedEventArgs e)
        {
            thread = new Thread(ExecuteLong);
            var task = Task.Run(() =>
                thread.Start());
            await task;
        }

        private void ExecuteLong()
        {
            try
            {
                // long task
            }
            catch (ThreadInterruptedException e)
            {
                MessageBox.Show("cancelled!");
                return;
            }
            MessageBox.Show("finished");
        }

        private void CancelButtonClick(object sender, RoutedEventArgs e)
        {
            this.thread.Interrupt();
        }

你能试试这个代码吗

    bool Stop = false;
    Thread thread;

    private void StartButton_Click(object sender, EventArgs e)
    {
        string FileName = @"...\a.bin";
        thread = new Thread(new ThreadStart(() => DoLongProcess(FileName)));
        thread.IsBackground = true;
        thread.Start();
    }

    private void StopButton_Click(object sender, EventArgs e)
    {
        Stop = true;
    }


    private void DoLongProcess(string file)
    {
        using (BinaryReader reader = new BinaryReader(File.Open(file, FileMode.Open)))
        {
            int pos = 0;
            int length = (int)reader.BaseStream.Length;
            while (pos < length)
            {
                if (Stop)
                    thread.Abort();
                // using Invoke if you want cross UI objects
                this.Invoke((MethodInvoker)delegate
                {
                    label1.Text = pos.ToString();
                });
                pos += sizeof(int);
            }
        }
    }
bool-Stop=false;
螺纹;
私有无效开始按钮单击(对象发送者,事件参数e)
{
字符串文件名=@“…\a.bin”;
线程=新线程(新线程开始(()=>DoLongProcess(文件名));
thread.IsBackground=true;
thread.Start();
}
私有无效停止按钮\u单击(对象发送者,事件参数e)
{
停止=真;
}
私有void DoLongProcess(字符串文件)
{
使用(BinaryReader=newBinaryReader(File.Open(File,FileMode.Open)))
{
int pos=0;
int length=(int)reader.BaseStream.length;
while(pos
贝波什的回答很好。为了进一步提高性能,您可以在设置“thread.IsBackground=true;”之后立即设置“.Priority=ThreadPriority.overnormal”,从而设置“thread”的ThreadPriority;“

在额外线程(而不是UI线程)上运行代码不应将性能降低四倍(它也不应该真正提高性能,因为所做的工作与处理几个窗口消息完全相同)。您还更改了什么?您如何处理原始代码没有更改的
CancellationToken
?您应该使用
TaskCreationOptions.LongRunning
如果操作需要12分钟,不会导致您看到的4倍减速。您的LongRunningFunction()是否有机会更新UI(通过使用Dispatcher或任何其他机制)?。如果不是,我根本看不出它会如何影响性能。大家好,请参阅我在“更新”下面的原始帖子。添加CancelationToken是为了在按下停止按钮时能够停止处理,因为我添加了一个线程,以便添加停止按钮,因为在处理完成时没有线程,UI会冻结,我无法停止。该函数不更新UI,只将行保存到输出txt文件。Hi CodeCaster.The while用于以1024字节为单位读取超过2GB的文件,然后循环运行约200万次。
var task=task.Run(()=>thread.Start());wait task;
这段代码没有任何意义。你好,bebosh。我添加了一个TestButton并使用了您的代码,但是如何添加示例的结构以使用字符串参数运行我的函数,并能够使用stop按钮随时取消?谢谢bebosh,请在原始帖子中查看我的更新3。我仍然有疑问在如何在my function.Hi bebosh中应用您的示例中,问题是函数需要调用一个字符串参数。定义为“private void DoLongProcess(string file){..}”。然后在StartButton中,单击()应该被称为“thread=new thread(new ThreadStart(DoLongProcess(filename));”但是当我在你的代码中这样做时,我收到了错误。错误是“没有重载方法‘DoLongProcess’接受一个参数(CS1501)”。我认为“ThreadStart(Function)”可以很好地工作,但是“ThreadStart(Function(argument))”不被接受。非常好,这一次它与你所做的修复一起工作。非常感谢你的帮助