Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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
避免Parallel.ForEach(C#Xamarin Android)期间ProgressDialog冻结_C#_Android_Asynchronous_Parallel Processing_Progressdialog - Fatal编程技术网

避免Parallel.ForEach(C#Xamarin Android)期间ProgressDialog冻结

避免Parallel.ForEach(C#Xamarin Android)期间ProgressDialog冻结,c#,android,asynchronous,parallel-processing,progressdialog,C#,Android,Asynchronous,Parallel Processing,Progressdialog,基于stackoverflow的主题和示例,我编写了一个“IP地址服务器搜索器”,试图通过http连接到192.168.x.1-192.168.x.254的所有可能的IP地址,以查找在特定端口上服务的前两台PC 它工作正常,对话框显示并更新1…254,只要: -我将连接超时时间保持在并行循环内的2000ms(36sec),或 -我减少到200ms,但是在不使用并行的情况下一个接一个地(需要22秒)!:D) 但是如果我通过设置:.ConnectTimeout=200来加快进程;让它平行运行>> -

基于stackoverflow的主题和示例,我编写了一个“IP地址服务器搜索器”,试图通过http连接到192.168.x.1-192.168.x.254的所有可能的IP地址,以查找在特定端口上服务的前两台PC

它工作正常,对话框显示并更新1…254,只要:
-我将连接超时时间保持在并行循环内的2000ms36sec),或
-我减少到200ms,但是在不使用并行的情况下一个接一个地(需要22秒)!:D)

但是如果我通过设置:.ConnectTimeout=200来加快进程;让它平行运行>> -对话框将在0%停止
-8秒后,它找到2个IP,
-完成作业后,对话框消失。
(无进程更新:()

以下是按钮的代码:

<!-- language: lang-cs -->
btnSearchAddress.Click += delegate {
    // ... get IP address of the WifiManager
    _PzzCID._myIPstring = Formatter.FormatIpAddress(i);

    // SHOW % in a dialog bar
    ProgressDialog progress;            
    progress = new Android.App.ProgressDialog( this );
    progress.SetCancelable(false);  
    _dialogCancelled = false; // static bool ... defined below
    progress.SetButton(-3, "STOP", (sender, e) => { // cancelling the search
        _dialogCancelled = true;
    });
    progress.Max = _MaxIP; // =254
    progress.SetIcon(Android.Resource.Drawable.IcMenuSearch);
    progress.SetProgressStyle(ProgressDialogStyle.Horizontal);  
    progress.SetMessage("Tested / Found IP addresses...");  
    progress.Show();

    var task = Task.Run( async () => { 
        await Task.Yield(); // force to run the commands from now on Async
        _FIND( edtPort.Text, edtDevicename.Text ); 
        while ( ! _dialogCancelled ) { //
            await Task.Delay( TimeSpan.FromMilliseconds(100));
            RunOnUiThread(() => {
                progress.Progress = _started.Value;
                //progress.Notify(); // would cause "not locked by thread ..." error
            });             
        };
        await Task.WhenAll();
        if (progress.IsShowing)
            progress.Dismiss();

        for (int j = 0; j < _addresses.Count; j++) {
            _PzzCID.AddLog2List(_addresses[j]);
            if (j==0) RunOnUiThread(() => edtBaseurl1.Text = _addresses[0]); 
            if (j==1) RunOnUiThread(() => edtBaseurl2.Text = _addresses[1]);
        }    
    });
}; // btnSearchAddress.Click

btnSearchAddress。单击+=委托{
//…获取WifiManager的IP地址
_pzcid._myIPstring=Formatter.FormatIpAddress(i);
//在对话框栏中显示%
进程对话进程;
progress=newandroid.App.ProgressDialog(此对话框);
进度。可设置可取消(false);
_dialogCancelled=false;//静态bool…定义如下
progress.SetButton(-3,“停止”,(发送方,e)=>{//取消搜索
_dialogCancelled=true;
});
progress.Max=_MaxIP;//=254
SetIcon(Android.Resource.Drawable.IcMenuSearch);
progress.SetProgressStyle(ProgressDialogStyle.Horizontal);
progress.SetMessage(“已测试/找到IP地址…”);
progress.Show();
var task=task.Run(异步()=>{
wait Task.Yield();//强制从现在开始异步运行命令
_查找(edtPort.Text,edtDevicename.Text);
而(!\u对话框已取消){//
等待任务延迟(时间跨度从毫秒(100));
RunOnUiThread(()=>{
progress.progress=\u start.Value;
//progress.Notify();//将导致“未被线程锁定…”错误
});             
};
等待任务;
if(progress.IsShowing)
进步。解散();
对于(int j=0;j<\u addresses.Count;j++){
_pzcid.AddLog2List(_地址[j]);
如果(j==0)RunOnUiThread(()=>edtBaseurl1.Text=_地址[0]);
如果(j==1)RunOnUiThread(()=>edtBaseurl2.Text=_地址[1]);
}    
});
};//btnSearchAddress。单击
这是一个称为搜索循环的异步:

const int _MaxIP = 254;
public static bool _dialogCancelled = false;

public static MultiThreadValues.ThreadSafeInt _started  = new MultiThreadValues.ThreadSafeInt(); // how many servers responded 
public static MultiThreadValues.ThreadSafeInt _found    = new MultiThreadValues.ThreadSafeInt(); // how many servers responded 
public static MultiThreadValues.ThreadSafeList<string> _addresses = new MultiThreadValues.ThreadSafeList<string>(); // each IP with server, who responded


public static async void _FIND( string port, string name ) { 
    await Task.Yield();
    _started.Value = 0;
    _found.Value   = 0;
    _addresses.Clear();
    string p = _PzzCID._myIPstring;
    if (p == "") return;
    const Char _dot = '.';

    StringBuilder str192 = new StringBuilder(64);
    Int16 dots = 0;
    for (int c = 0; c < p.Length; c++) {
        if ( p[c] == _dot)  dots++;
        str192.Append(p[c]);
        if (dots == 3) break; // found 3. "." = 192.168.1.
    }
    string str192168 = str192.ToString();

    const Int16 _numberOfthreads = 8;

    IEnumerable<int> _all_1_to_254 = Enumerable.Range (1, _MaxIP);
    // Parallel.ForEach(GetRateLimitedResource,
    Parallel.ForEach(_all_1_to_254, new ParallelOptions() { MaxDegreeOfParallelism = _numberOfthreads }, 
    async (i, StopMe) => {
        await Task.Yield();
        _started.Add1();
        //int s = _started.Value;
        //if (s < _numberOfthreads) Thread.Sleep(500 * s); // useless

        bool success = false;
        var host0 = str192168 + i;
            string url_txt = WebCall.CreateTestURL(host0, port, name) ;
            URL myUrl = new URL (url_txt);
            try {
                using (HttpURLConnection urlc = (HttpURLConnection)myUrl.OpenConnection ()) {
                    urlc.RequestMethod = "GET";  //OR  urlc.setRequestMethod ("HEAD"); 
                    urlc.SetRequestProperty("Connection", "close");
                    urlc.ConnectTimeout = 200;
                    await urlc.ConnectAsync();
                    success = (urlc.ResponseCode == HttpStatus.Ok); 
                }
            }
            catch (Exception ex) {
                //_addresses.Add("**ERROR:"+url_txt+ " --- " + ex.Message);
            }
            myUrl.Dispose();

        if (success) {
            _found.Add1();
            _addresses.Add(host0);
            if (_found.Value == 2) {
                StopMe.Stop(); // Found 2 hosts >> Exit from for-loop
            }
        }

        if (_dialogCancelled &&  ! StopMe.IsStopped)   StopMe.Stop(); // StopMe is a ForEach state 
    }); // lambra ForEach

    _dialogCancelled = true; // force finish >> to dismiss the ProcessDialog automatically
} //void _FIND()
const int_MaxIP=254;
公共静态bool\u dialogCancelled=false;
public static multi-threadvalues.ThreadSafeInt _start=新的多线程值。ThreadSafeInt();//有多少服务器响应
public static multi-threadvalues.ThreadSafeInt _found=新的多线程值。ThreadSafeInt();//有多少服务器响应
public static multi-threadvalues.ThreadSafeList _addresses=new multi-threadvalues.ThreadSafeList();//服务器的每个IP,谁响应
公共静态异步void _FIND(字符串端口,字符串名称){
等待任务;
_已启动。值=0;
_已找到。值=0;
_地址。清除();
字符串p=_pzcId._myIPstring;
如果(p==“”)返回;
常量字符_点=';
StringBuilder str192=新的StringBuilder(64);
Int16点=0;
对于(int c=0;c{
等待任务;
_start.Add1();
//int s=_start.Value;
//如果(s<_numberOfthreads)Thread.Sleep(500*s);//无用
布尔成功=假;
var host0=str192168+i;
字符串url_txt=WebCall.CreateTestURL(主机0、端口、名称);
URL myUrl=新URL(URL_txt);
试一试{
使用(HttpURLConnection urlc=(HttpURLConnection)myUrl.OpenConnection()){
urlc.RequestMethod=“GET”//或urlc.setRequestMethod(“HEAD”);
SetRequestProperty(“连接”、“关闭”);
urlc.ConnectTimeout=200;
等待urlc.ConnectAsync();
成功=(urlc.ResponseCode==HttpStatus.Ok);
}
}
捕获(例外情况除外){
//_地址。添加(“**错误:+url\u txt+”--“+ex.Message);
}
Dispose();
如果(成功){
_found.Add1();
_地址。添加(主机0);
如果(_found.Value==2){
StopMe.Stop();//找到2台主机>>退出for循环
}
}
如果(_dialogCancelled&&!StopMe.IsStopped)StopMe.Stop();//StopMe是ForEach状态
});//lambra ForEach
_dialogCancelled=true;//强制完成>>自动关闭ProcessDialog
}//void _FIND()
问:在CPU负载很重的情况下,如何强制更新(刷新)ProcessDialog?

(如果还有什么我可以改进的,请与我分享!:)

你说的强制升级是什么意思?@mjwills:对不起,mistypo.编辑为:[强制更新(刷新)]