WPF套接字客户端结构

时间:2018-08-19 15:33:51

标签: c# wpf sockets mvvm

我的问题似乎有些奇怪,但是使用MVVM模式创建WPF套接字客户端的最佳方法是什么。

现在在我的ViewModel上,我创建一个线程,该线程尝试在while循环中连接到服务器,并在连接后等待连接,它从服务器获取数据。

是否有更好的方法可以使我不必阻塞主UI线程而不必使用新线程?

相关的ViewModel代码:

    serverInfo.ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverInfo.PORT = 1488;
//Initialize LeecherList
p_LeecherList = new ObservableCollection<LeecherDetails>();
//Subscribe to CollectionChanged Event
p_LeecherList.CollectionChanged += OnLeecherListchanged;

AccountsInfo = JsonConvert.DeserializeObject<RootObject>(File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(), "Accounts.json")));
foreach (var x in AccountsInfo.Accounts)
{
    p_LeecherList.Add(new LeecherDetails("N/A", x.Email, x.Password, false, "Collapsed"));
}

base.RaisePropertyChangedEvent("LeecherList");

Thread ConnectionLoop = new Thread(() =>
{
    ServerStatus = "Connecting...";
    while (true)
    {
        if (!serverInfo.HasConnectedOnce && !serverInfo.ClientSocket.Connected)
        {
            try
            {
                serverInfo.ClientSocket.Connect(IPAddress.Loopback, serverInfo.PORT);
            }
            catch (SocketException)
            {
            }
        }
        else if (serverInfo.ClientSocket.Connected && !serverInfo.HasConnectedOnce)
        {
            serverInfo.HasConnectedOnce = true;
            ServerStatus = "Online";
            break;
        }
    }
    while (true)
    {
        try
        {
            var buffer = new byte[8000];
            int received = serverInfo.ClientSocket.Receive(buffer, SocketFlags.None);
            if (received == 0) return;
            var data = new byte[received];
            Array.Copy(buffer, data, received);
            var st = helper.ByteToObject(data);
            if (st is string info)
            {
            }
            else
            {

            }
        }
        catch
        {
            continue;
        }
    }
});
ConnectionLoop.IsBackground = true;
ConnectionLoop.Start();

谢谢。

1 个答案:

答案 0 :(得分:1)

  

现在在我的ViewModel上,我创建一个线程,该线程尝试在while循环中连接到服务器,并在连接后等待连接,它从服务器获取数据。

     

是否有更好的方法可以使我不必阻塞主UI线程而不必使用新线程?

好吧;您应该将这种逻辑放在Service中。

示例:


因此,您可以创建一个这样的服务,注意:启动,停止和传递数据的事件。

基本思想是将更多类似业务的通信逻辑移到单独的服务中,这样,如果您以后需要对其进行更改,则该逻辑将更加孤立并且不会与视图模型混合。

//note, you could encapsulate functionality in an interface, e.g.: IService
public class SomeService 
{
     public event EventHandler<YourEventData> OnSomethingHappening;
     public SomeService(some parameters)
     {
         //some init procedure
     }

     public void Stop()
     {
        //your stop logic
     }

     public void Start()
     {
        //your start logic
     }

     private void Runner() //this might run on a seperate thread
     {
         while(running)
         { 
             if (somecondition)
             {
                  OnSomethingHappening?.Invoke(this, new YourEventData());
             }
         }
     }

     public string SomeFooPropertyToGetOrSetData {get;set;}
}

也许在启动时在应用程序中的某个位置创建其中之一。

然后将其传递给您的视图模型,也许通过构造函数。在这种情况下,您的视图模型将如下所示:

public class YourViewModel
{
     private SomeService_service;
     public YourViewModel(SomeServiceyourService)
     {
          _service = yourService;
          _service.OnSomethingHappening += (s,a) =>
          {
              //event handling
          };
     }
}

//etc.