zoukankan      html  css  js  c++  java
  • 多线程调用中的注意事项

    注意:

    1、不管是哪种多线程方法,在线程中访问共享资源的时候一定要用lock锁起来!不然会由于冲突产生各种奇奇怪怪的问题。

    2、委托(含拉姆达表达式)中调用的方法,其参数如果是变量,它的值取决于运行的那一刻内存里的值。如果希望在创建任务的时候值是固定的,必须用object参数state作为创建任务的状态,把值给进去。(也就是《编译原理》中的“编译时”和“运行时”的差别)

    3、而对于委托的begininvoke方法,里面的回调参数,是IAsyncResult类型。需要用它的“AsyncState”属性(object类型)获取传入的的内容(这一点跟代码提示的内容不一样)。

    如果不太理解,看例子:

    对于第一点

     1 public partial class Form1 : Form
     2     {
     3         public Form1()
     4         {
     5             InitializeComponent();
     6             pBar1.Maximum = 200;
     7             pBar1.Step = 1;
     8             CheckForIllegalCrossThreadCalls = false;
     9         }
    10 
    11         private void button1_Click(object sender, EventArgs e)
    12         {
    13             for (int i = 1; i <=100; i++)
    14             {
    15                 for (int j = 80; j <=81; j++)
    16                 {
    17                     ThreadPool.QueueUserWorkItem(tryconnect, new MyData(i, j));
    18                 }
    19             }
    20         }
    21         void tryconnect(object o)
    22         {
    23             int i, j;
    24             i = ((MyData)o).x;
    25             j = ((MyData)o).y;
    26             TcpClient tcp = new TcpClient();
    27             IAsyncResult async = tcp.BeginConnect(IPAddress.Parse($"192.168.1.{i}"), j, null, null);
    28             async.AsyncWaitHandle.WaitOne(1000);
    29             lock(listBox1)
    30             if (async.IsCompleted)
    31             {
    32                 listBox1.Items.Add($"192.168.1.{i}:{j} is open.");
    33             }
    34             else
    35             {
    36                 listBox1.Items.Add($"192.168.1.{i}:{j} is closed.");
    37             }
    38             //pBar1.PerformStep();
    39             tcp.Close();
    40             lock (pBar1)
    41             pBar1.PerformStep();
    42         }
    43 
    44         private void button2_Click(object sender, EventArgs e)
    45         {
    46             Close();
    47         }
    48     }
    49     class MyData
    50     {
    51         public int x, y;
    52         public MyData(int a,int b)
    53         {
    54             x = a;
    55             y = b;
    56         }
    57     }

    对于这种密集的异步线程,再调用异步tcp连接,如果没有第29行的lock,在vs下调试时关闭窗口的时候就有很大概率出现下图的错误:

     争夺资源越激烈概率越大,像代码中那样200次连接,已经是必然发生了。4次连接,大概25%左右发生概率。

    编译完成的应用直接打开,退出的时候会出现一个错误框,一闪而逝,不注意看不到。

    貌似不影响用户使用,但毕竟是隐患。

  • 相关阅读:
    HDU 1269 迷宫城堡
    HDU 4771 Stealing Harry Potter's Precious
    HDU 4772 Zhuge Liang's Password
    HDU 1690 Bus System
    HDU 2112 HDU Today
    HDU 1385 Minimum Transport Cost
    HDU 1596 find the safest road
    HDU 2680 Choose the best route
    HDU 2066 一个人的旅行
    AssetBundle管理机制(下)
  • 原文地址:https://www.cnblogs.com/wanjinliu/p/12766141.html
Copyright © 2011-2022 走看看